 So today we're going to wrap up the lecture on application and security, Adam is in here, so I'll be finishing up the slides for you guys. And after the lecture, we're going to have like a two class office hours, so if you have any questions about the assignment, you can just walk up to, we walk around the rooms and answer those. That's why we brought a laptop? Yeah, that's why we brought a laptop. Alright. So before we talk about various security techniques for the staff, we talked about the non-interviewable staff, where basically any code that you put on the staff will actually run if you jump into it. And now we want to make that even harder by preventing actual data overwrite. So the subject of doing the assignment right now is attempting to write some value onto the safe EIT set, and that's what we'll be trying to do. So a technique that is used to do this is called canaries, and this name comes from coal mining, where the miners would use burbs to detect whether or not there was enough oxygen down there. And then the burbs start showing signs that would make a leak or something like that. So the first technique that came out from these canaries was called stack art, and this basically follows right after the nines do the stack. So the idea of canaries is putting some value on the stack as like a sanity check before the address they want to overwrite. So you're putting some value on the stack, and then you're verifying that value before jumping to whatever address is on the stack. So the first type of canary is a terminated canary, which is null by a character termed line feeder EOL, and let me know why they picked this as a sanity check. Let's take a look at the diagram. Are you with all four bytes, or is one of those four bytes? Well, let me pull up this chart, and then we'll take a look at that. Okay. So we're going to go back to the vertical stack, sorry guys. If you like the horizontal one. This is the way that I was going to explain that. So you can see here at the very top of the stack, the return address is what you want to overwrite through like a buffer for example. And the canary value is just below that, so that if you were to overwrite the return address, you can also overwrite the canary. So going back to what we talked about earlier, why would they put null as the canary value? Because you have to write a zero. What was that? You have to write a zero, so a zero would be in your shell code. Exactly. And then stir copy would stop at that zero, you know, before overwriting. So it's kind of like a sand check to make sure that you can't do that. But that's easy to get around unfortunately. So there's another type of canary called the random canary where they put some value that's supposed to be unknown to the attacker in that spot on the stack. And then before the jump instruction, there's code that will check that canary value to see if it's been modified or not. And the way this works is that there's additional instructions added to the program itself, so you'd have to recompile something to be able to have the canary support. And it is supported at 30 white in nowadays. This is not that kind of stuff. So because the random value is supposed to be unknown, what they do is they pad it somewhere in memory with unreadable sections, so that if you were to try to read memory sequentially to get at the stored canary value, you would get a segmentation fault. So unless you know the exact address of the canary value, you wouldn't be able to read it. But again, it doesn't offer protection if you actually are able to read specific memory locations. So then they came up with one other tip. And that's the next order canary where they're basically calculating the canary value using some random value and the address that you're wanting to protect. So in this way, the attacker would need to know the original chump address and the random canary value and the algorithm for the XOR before being able to successfully overwrite that. So like I said, there's modifications in code to make this canary protection happen. And that obviously introduces overhead. So I don't think it's too much, but you don't want to be putting canaries on every single value in your program. So GCC, I think, as a version 4.8 supports canaries by default. So you actually have to say have to know it's that protective if you want to say otherwise it'll be on. And girl police is one of the locations that was used. That's only if it does the first two types of canary so that it doesn't do XORs. I'm not 100% sure on that, but I think that's right. And another thing that these tools do is they rearrange the variables so that let's say you have a buffer somewhere as a local variable interfunction. That buffer shouldn't be behind any other variables. So if you overflow the buffer you don't overflow any other locals in the function because that might alter behavior in other ways. So if you want to learn more about this stuff. So like I said, canaries are not foolproof. One easy way to get around them is just not to touch them. If you don't touch them and they stay in their original form then they're not going to offer any protection. And not everything has a canary either. So mainly just the return address made of base pointer. It doesn't protect against garbage sharing memories either. If you have full control of the process then you can override the canary with the correct value. So in Windows there's a gs compiler option which adds canaries and that should also support password canaries. I'm not sure if it's default or not it probably is though. So one interesting attack against canaries exploits pretty big vulnerability of the system and that is that a process supports or a certain new threat that canaries don't change. So if you have like let's say a web server that has canaries protecting some values on the stack you could attack each individual threat, get that threat to restart itself and then run the same attack without having to worry about different canary values. So that's what this Brock, a black or green orange program is. And there's a link to Brock. So there's a link to Brock a very interesting research paper on how they get around breaking canaries into a partial observer which supports the exact the only way to get new canaries is to start a learning process. One thing I forgot to mention is that in order to be able to attack these vulnerabilities of canaries you have to be able to exploit some sort of stack vulnerability. So if there's no stack vulnerability then you can't hold on to this. But assuming there's a stack vulnerability you can overwrite the canaries in a pretty simple manner. So let's say the canary value is some 32 bit or yeah, it's a 32 bit XOR value of the return address. And that's going to comprise of four bytes, right? So what you can do in the Brock attack is instead of guessing the whole canary value which would give you a search space of four million or something, four billion, you can do it byte by byte. You can alter one byte of the canary, check to see if the server crashed or not. If it crashed then you increment that value, right? And then you try it to 226 times times four days or six. So you've gone from four billion search space to a thousand which is really good. So another technique that's also pretty much becoming mainstream nowadays is control flow integrity. And here I don't know if you guys use either Pro or some other tool when doing the password don't work. Do you start out there that there was a control flow graph with different basic blocks following edges for jumps, right? So the idea with control flow integrity is we analyze the program on the front, generate that control flow graph and the possible edges that the jumps can take and then verify that the jumps happening inside the program are actually legitimate jumps and not jumps in some arbitrary address. So for control flow integrity this is actually a pretty big topic so I recommend you guys check this out on your own. But it is a very powerful technique and it's as of I believe the November 2017 update of Windows Hazard for all the current code. So this is actually being used nowadays to protect the Windows stuff. And the way it works is it maintains state of all the legal jumps in some bitmap, for example. And that bitmap also needs to be protected. So it was those those that used this hyper-releaching to kind of virtualize that and make sure other processes can't. In control flow integrity there's four basic types of checks. The first check is for call instructions which are direct jumps. And a direct jump is basically a jump to some statically defined function of the program. So that's a pretty simple thing if there's a call instruction that should go to real function not to fake function. The nice type of protection is for jumps. So here you have some pointer in the memory address that you can be jumping to it's like a function pointer, for example. And it's a little bit harder to do this check because in addition to allowing legitimate function pointers you also have to allow jumps within the current function. You're allowed to jump lower or higher within the same function. So there's a little bit more logic to that. And then I think the most important type of controls I'm going to be checking is sometimes referred to as reverse or backwards edge checking. And this is actually verifying that the return address is being retrieved from the stack. It's like the save VIP. They're verifying that the save VIP actually takes you to one line below some call or jump instruction. So it's not going to some random place. And this can be combined with two S6 to, for example, identify rock gadgets or short combinations of instructions to see if you're jumping to that. Then it's probably an exploit and a problem can be practically significant. So there we go. So in order to get controls on time, you have to work. The compiler also has to modify the binding. This doesn't have to be done in source. It could be done through assembly also. But in either case, it's a process called instrumentation where they're adding additional checks into the code to make this kind of detergent checking possible. And as you can see here what happens is it's checking to see that the callback argument is a valid target within the program, and not some random shell code, for example. And if it's valid, then the control continues. If it's not valid, then it'll just terminate the program through some instruction that's baked into the program. So I think that's it for controls on time. And I remember going to something really awesome. And that's a math exploit. But basically, this is the framework to carry out various next points. It has a database of known attacks and vulnerabilities across a variety of platforms. And essentially what you do is you select a vulnerability from the tool. You pick some payload that's going to trigger that vulnerability. You pick an encoding that might bypass the firewall. So if a system is protecting a specific port, or if it's looking for some string, you want to use a different port or encode it in some way that that string isn't visible to the firewall. And then you just run the exploit through MathsPlayer. And it is available as a version. There's also a professional version of the software which I guess is used by penetration testers and security professionals and whatnot. So, the spring is off already. You just pick an exploit and run it. Does that mean that all of our manual testing is obsolete? Do we even need to bother with graphing shell code or checking addresses? We have a tool that's got all the known exploits. It plays human insight as a database of vulnerabilities because most security issues are zeroed in. You don't know about them when they're being exploited. So these sorts of tools aren't something that you should switch to. It's something you can use in addition to other security techniques that we've talked about. So along those lines are there automated tools that can find zeroed-in vulnerabilities that haven't ever been seen before? You hope so. The answer is yes, there are. That's a pretty cutting edge area of research right now. I think Metasploit does do a little bit of this, but not really in depth. There's a technique called buzz testing which basically generates random inputs in some programmatic manner and then tests it against the target program and you might actually get some crashes through that way. It's a very powerful technique and when you combine it with other techniques to more carefully traverse through the different basic blocks of binary then you can actually discover new crashes that have never been seen before. But that's not something that Metasploit does for you. There are other research paper and other tools out there because you'll search for fuzzing or symbolic executions and other techniques. Those are really cutting edge research ideas. Wouldn't that almost be like starting as like a black box test and then figuring out how the inputs change? Kind of, yeah, absolutely. It's not quite that simple, but the idea is that the tool will automate a lot of other things and then when the human insights need it to guide the tool you can narrow your focus and then hopefully deliver a payload that will do it more. So, wrapping up this whole section on application security essentially you can see that to do exploits we had to come up with inputs that the program isn't really expecting. It could be command line arguments it could be the environment it could be the operating system it could be hardware. There's a lot of different methods that you can use to act stuff. And the key defense is sanitizing the input and making sure that the logical checks you're making are complete and they cannot omit any important things or using normal functions. So all these things together allow you to write safer software. And to summarize, so we have ASLR, we have the non-executive stack, we have canaries and we have controls on tiger team. Does that mean that all modern applications are safe from member corrosion? So if you have all these things enabled on a program, is it safe? Is it guaranteed? Okay, to be more specific how might the protections How might the protections not be enough? All of this is looked at the stack so far. There is the heat as well, but is there any sort of way? The same ideas really go for that. So the thing is what these exploits is, yeah I mean with these protections is that there's always a cat asking going on between hackers and security engineers. And there's new techniques such as it's called co-op counterfeit object oriented programming which actually is able to defeat the control flow integrity by creating fake objects in C++ so these use virtual functions that can be used to fool the control flow integrity checks because they're actual methods that are just being overrated like a rom style approach. So there's always this cat but the other bigger concept is is everything always going to be enabled? Is every single binary going to have every single protection all the time? Probably not. There might be a case where you disable some protections for speed or a legacy system or maybe it's not available so you'd be aware of the limitations of these protections and don't rely on them as a replacement for writing a safe code because memory leaks I mean memory exposure and applications if you look up the recent exploits they're all based on memory being exposed and arbitrated means. So here I wrap it up. Do you guys have any other questions? If not we're going to go ahead and jump into the office hours. So we'll just walk around and answer whatever questions you might have on the assignment which is due tomorrow night. Bye.