 Okay, I will demonstrate now the buffer overflow attack and we will discuss the defences against this attack. We here have a simple program containing a main function and the second function called serve which is called from main with a pointer, so everybody just look at this program. Now the second function is called, is being called from the main function from here with the pointer buffer one passed. Now the main, in the main program, main program declares a character buffer and initializes it with the string hello world and the serve function it receives a pointer to character and copies the contents of that the pointer into a local buffer which is declared with size 12 bytes and with the help of the string copy function. Now there are some print statements in the program which show the contents of the buffer in the sub function before calling the string copy function we display the contents of buffer 2 and after returning back from the string copy function. We will first execute and see the output of this program. Now I am compiling the program with some flags, we will see what these flags mean while discussing about the defences. Now this is the output of the program when the buffer 1 in the main is initialized with the hello world string, actually this string is being copied into the buffer 2 in main function using string copy. Now the output in the first statement printed is inside main function and the content of the buffer 1 is hello world. Now when the inside when the program control goes into the sub function it trains the contents of buffer 2 declared here locally which is initialized with all a's as we can see here and after the string copy function it changes to hello world and when the function sub returns completes its execution it comes back to the main function and there is print indicating it has returned to the main. Now are there any questions about this? So there is a main program which is calling a sub routine so Parmeshwar has added quite a few statements over there to make things clear. As you can see in the sub routine you first print out the content of buffer 2 which is all a's it's initialized to all a's then you do the string copy so this is the so where is the vulnerability this is the vulnerable function this is what you shouldn't have used this string copy function because it doesn't check for array bounds. So it's copying from buffer 2 or it's copying to buffer 2 from buffer 1. So buffer 1 has been initialized with hello world in this particular program and so it's copying so you can see when he executes this thing that initially buffer 2 has all a's and then it has hello world. So up to here things are clear we're going to get a little bit more and more complicated to proceed. Now keeping everything same if I initialize buffer 1 in main program with the string that is shown at the bottom which is a carefully crafted string to exploit the vulnerability in this program. Now what he's going to do is in buffer 1 he's going to load it with this particular string. Does anybody have any feel for what is going on inside this string? What does it contain? Code. Code. You mean assembly code? Machine code? Yeah. For which language? So you're a worm writer you're writing this thing exactly this is what happens in the case of code read. The guy crafts that buffer something like this it is going to contain what? X codes. X code but which language? Assembly code for what? Assembly code for. Which is the most obvious assembly code for the spark machine? 86. 86. So X86 assembly code and there's some interesting things that you see about this code. You see 1990, 1990 what on earth is this 90 you make a guess what do you think is that is that an instruction or is that some data or what? That thing is going to change the return address. So the question is it data? Is it machine code? Is it the address? The three different things. It is an address. Return address is 1990, 1990. There must be some weird thing going on over there right why do I have 1990, 1990 data what is 19 in ASCII is that really so ASCII of a is 90 make a guess anybody could guess what is this machine code what instruction again and again I'm doing the same thing what is it XOR something or something like that just look at how much effort the worm writer has to spend in crafting these things you don't want to put 00 inside this you know why that is the termination of a string the null character so if there is 00 in the machine code you will substitute for an XOR instruction for instance XOR a register with itself is 0 all sorts of little things have to be carefully considered so believe it or not I'm going to tell you the answer you tell me why this is so 90 is machine code in X86 for the NOOP instruction why do I have so many NOOPs just one NOOP and repeated again and again 90 is one NOOP and I'm repeating it again and again and again and then I've got some other instructions over there presumably it's no operation yeah I'm not you know no operation so why do I have this after the that means after cycles cycles it has to execute to steal that is to just pass time time pass that is the buffer that is I'm sorry and that code wants to override that return our address the code wants to override the return address the return address will be overwritten but by what by rest of the instructions not by this you want to override the address by instructions or you want to override the address by some other address so these these no operation hex byte will occupy those many bytes to come to that byte which contains the written address okay fine but why couldn't I put the return address to point to the first instruction why do this time pass and NOOPs the return address of the main function will be at that location it is a stack frame that is that actually in the buffer the first are allotted to the particular buffer it should work though that is it should match with the correct return address should be stored so I have to calculate carefully carefully yeah definitely one thing I have to calculate carefully where is the return address addresses wherever I see the return address on that stack frame there I have to plant something else that something is going to be the address of the malware now the malware in this case is simple malware you can again do a Google search and find actual malware that creates a shell it's called shell code do a Google search on shell code we're not doing shell code over here but what we do is that return address has to point to something that is going to execute that execution is done that thing that executes is also part of this thing okay and that executable is just basically a system called as permission will explain now where is the return address and what is the code he's going to talk about in a second okay first we'll see the output of this program when the buffer one is initialized with this thing will compile the program if you see at the output in the main function but the content of buffer one is some is the characters corresponding to the hex code that is present in our attack string and inside the sub function the content inside sub function at the bottom before calling the string copy function the contents of buffer 2 is all initialized with all a's and now after calling the string copy function the contents will be changed to the one that is present in buffer 1 the contents of buffer 1 is copied into the buffer 2 and we see that the size of buffer 2 is actually only 12 bytes but the string being copied is for large in size so and also when the function sub completes its execution it is not coming back to the main as we can see because the return to main that statement is not being executed we will see as to why this is happening by looking at the contents of stack just before the string copy function is being called and after the string copy function is called means in the sub function at line 8 we will see the contents of stack on line 8 and on line 10 just once again to clarify what is saying is that that print statement in main you don't see it right now that print statement being returned to main that doesn't execute what does that suggest did the sub routine return back to the main program if it returned back then you would have seen that return to main string printed out but it was not printed out so where did this sub routine go what has happened exactly now he'll tell you look at the stack on the left the stack on the left represents the content of contents of the stack before calling the string copy function and to the right the contents after the string copy function is called now the stack is growing in the upward direction and memory addresses are growing in the downward direction the shaded portion on the stack is the stack frame for sub function when it is called from main buffer one is pushed on the stack which is pointing to the buffer one which is pointing to buffer one which is present in the main which which contains hello world string initialized and then after the buffer one it pushes return address where to come back after execution of sub function where to return back in the main function it is the return address is pushed and when the sub function starts execution it will first push the frame pointer of the previous of the calling function in this case the main function frame pointer of the main function is pushed and a canary value which we will look into when we will discuss the defenses you used and above the canary value sub function allocate space for buffer 2 it starts from here and first it initializes with all a's and after the string copy function is called it will start copying the contents of buffer 1 into buffer 2 and we can see the result to the right on this here now the contents of buffer 2 is changed it is in the first case when the string being copied is less than the size of the buffer 2 it is less than 12 bytes so it is successfully copied and the fields below it will not be disturbed so in the second case when I initialize buffer 1 with the attack string which is which is very large than this the large than the size that buffer 2 can hold rest of the things remain same only buffer 1 is very large and we can see after the string copy function is called it will start copying buffer 1 into buffer 2 here it will start from here actually it should have stopped here after 12 bytes but it will it will go on copying the this attack string and it will it will stop only after it has completely copied buffer 1 into buffer 2 so now the result being that the return address has been now overwritten and it is now pointing to the start of buffer 2 so after the the function sub function completes execution of all its instruction and is about to return back to the main now it will now the return address has been changed so the execution will start from here from this address so this code is actually the the compiled hex binary where equivalent of the instructions which we which are invoked to which are executed to invoke exit system call so actually from here point point from this point on the exit system call will be invoked so the program is exiting from this that is why the program is not coming back to the main everybody knows what is a system call right system calls are the way to get into the operating system you want to read a file open a file etc you make a system call you get into the kernel at that point you ask the kernel for services the same thing over here what he's talking about is a system call by the name of exit you exit naturally without creating any problems and that is why you do not return to the main program so what he has done he has put the machine code x86 machine call code for executing the exit system call where you exit naturally without a problem that's why it is not coming back returning to the main function now we will look at the contents of the string the attack string that in the initial part of the string there are no op instructions the hex code for no op instruction is 90 and the rest of the instructions in this table are used to invoke the exit system call now the now the hex code for XOR instruction we can see here 3 1 DB which is here 2 bytes long and the in the part of the string that is highlighted with red color is actually the return is the new return address which is pointing to the start of the buffer to now the defense is used to counter the buffer overflow attack one thing is we can use the canary values when a function is called that function will save a canary value a random value after after the after up at the end of the buffer and while when it is about to exit the from the program when about to exit from the function call it will check if the same value is present if it is same then it is okay it will return return normally otherwise it will it will raise an exception so what is this defense exactly canary defense who's doing all this let us ask ourselves the question who's doing these things when a function has to be called who is pushing the arguments on the stack the calling program who's pushing the return address on the stack the hardware as part of the call instruction who is pushing this frame pointer this is the frame point of the calling program which was in a register which has to be saved so that it can be used by the calling program when it returns to the calling program who is doing this thing the called program or the sub routine who is doing this thing putting a canary value and what is this canary value let us see how it works look at the idea who's putting this canary value on the stack it is the compiler the compiler when he compiles this code for the sub routine has instructions to put a random value this is the critical point a random value so the hacker will not know what is this value a random value on the stack and then when the sub routine returns there'll be a part of that sub routine again inserted by the compiler to check whether the canary value is the same random value that it inserted there so at the start of that sub routine after the function the called function the sub routine sorry the sub routine pushes the frame pointer then the compiler pushes this canary value the compiler actually introduces that so this canary value is pushed on the stack this is a random value now watch what happens when the sub routine returns that canary value is checked to see whether it is still the same value is still on the stack if it is that means the buffer has not been overflown and if that value changes as you can see that is after the buffer here the value in this case the value is being it will change initially whatever the value is present it is being overwritten for the purpose of this demonstration I have disabled the all the defenses against stack this overflow attack that is why the program is working is not raising any exceptions so if if I enable the this canary protection and see the output I have enabled the canary protection and I will execute the program now it is it it it will not execute and it shows a message like this stack smashing detected here that is the one defense and the second defense against this overflow attack could be means by default it is it is the case that all the stack is non-executable for the for for this demonstration I have made the stack executable that's why the program is working if I if I make stack non-executable the default is the stack is non-executable now I will make I will return change the settings to default and execute so it gives me a segmentation fault that is because the stack is now non-executable and the CPU is trying to load instructions from there and execute that that's why it is giving segmentation fault now the third defense is to is to randomize the memory layout when each time the the program executes the stack is loaded to a different location the base address of the stack stacks starts from every time we execute it starts on a different location that's why in in in this case I have used a hard-coded address to jam to if every time if every time the stack is located is loaded to a different location then it will not work so this this defense is referred to as ASLR ASLR stands for address space layout randomization so basically what that is everybody knows that in virtual memory you've got multiple segments you got a code segment a stack segment etc etc now the base of the stack segment if I keep changing all the time then what will happen is I don't know exactly where is a return address those addresses are all virtual addresses so I don't know it might be this today it might be something tomorrow execute the same program that return address will be different so this is one other defense ASLR which is an operating system based defense the making the stack non executable is another defense operating system based defense the canary business is another defense but it is a compiler based defense and finally the use of safe string functions that is a programmer based defense don't use those vulnerable functions but use safe functions instead if you want to implement it in your content just look at all these different flags because you would be surprised if you try this program without putting the proper flags if you compile it without the proper flags the overflow will not work so make sure you put all these three flags by default all these three things are enabled which three things the canary option the stack made non executable and the ALSR thing so you have to specifically disable them for your buffer overflow attack to work anybody has some questions understood like what is buffer overflow I mean problem but how to get this I mean how to execute how to use this vulnerability okay suppose I do I in my system I don't have GCC suppose I am using CC only I'm sorry you're using see yeah I mean this is all these defensive mechanism is part of the compiler right well some operating system based some are compiler based yeah suppose I don't use any patches so think that the CC compiler or whatever whatever the architecture or the hardware has a buffer over problem how to exploit it exploit it okay so the first thing I do as a worm writer so I'm playing I'm using the hat of the worm writer the first thing is I figure out which subroutines have this buffer overflow problem so that's what was done in the case of the Microsoft IS they said that these subroutines have it and let us patch it so I first figure out which subroutines have the buffer overflow problem then I ask myself where did that thing where was that buffer populated from ultimately that thing has to come from user input from somewhere outside in the case of I in case of code read that outside thing was through an HTTP message so through the HTTP message all that stuff ultimately has to enter your computer it's got to be buffered somewhere that buffer was translated was transferred to this buffer in this subroutine and this subroutine had the buffer overflow problem so that's what I noticed I noticed that the HTTP request and the payload was being loaded into this buffer and then there was a subroutine that used those contents and that subroutine was carelessly written it didn't take care of buffer overflow and this 4k payload came and that thing was let's say 100 bytes it overflowed the entire thing completely and the mal code and everything the malicious code which is called shell code was actually on the stack so this is before the stack was made non executable and so on and so forth now with these defenses in place it is much harder to perform an exploit but still there are examples of this thing it's one of the most common exploits so there is some external payload some input from somewhere in this case from the network through an HTTP message when the HTTP message comes that payload is put into some buffer at some point in time the system takes that buffer and puts it somewhere else to process it that processing software has a buffer overflow vulnerability so this is what I noticed I reported it to Microsoft Microsoft delivered a patch most of the system administrators didn't take action problem so whatever code you have shown that is related to the standalone system yes but whatever buffer flow attack is there that will be coming from outside the network yes it has to come right this is input just think about it this is input crafted very carefully like he has done crafted by the worm writer yeah yes how you write the patch wherever you've got that subroutine you put a call another program and that program doesn't use string copy that string and copy or something which is which checks for a rebounds so instead of using string copy just use string and copy that is the subroutine of that is the function call that actually checks for a rebounds so can we have those compiling options to deactivate those one or three flags again can we have the compiler option to those we are those that fellow was providing in compiling option to deactivate those one or three flags yes yes so can we have to actually when you're compiling the program you have to you don't say you don't do anything you just compile it normally normal compilers these days will automatically enable those three defenses no if I want to deactivate them and I want to yes yes so he'll show you do you want to see them so while compiling I provide this first option is to disable stack protection if I've been FNO I've been stacked and protector everybody please notice this if you're trying to implement it in your college for a demo you better do this otherwise it will not work in front of the audience the other thing I just want to mention is the case with windows be a little careful there are these three things we told you these three defenses there are some there is some software in windows some modules in windows that actually use code on the stack to execute so you can't make this tax like for example signals you can't make the stack totally non executable on windows systems but you can do the other two things how to do it is a good question I don't think my student my students typically use Linux for this but I'm sure you can do that these demos can be only executed on Linux I would imagine they could be done in windows we have not done it as yet but I'm sure if we try we can yeah if we keep changing the memory layout how the operating system will remember where the return address is stored how will it know all these return addresses are typically displacements with respect to some base pointer okay so these all virtual addresses that will be translated to physical addresses so in virtual space I can put the base of that stack segment anywhere I want and just change the register the base register everything will automatically change thereafter second question is when we use canary values to cross check the again with the values and how does it remember it well the compiler stores it somewhere right so there is that code is written there is some special code injected by the compiler when that subroutine begins so I generate a random number I insert it over there on the stack and then just before I'm about to exit I checked that random number to see whether the same thing is retained or whether it's been changed if it's been changed then I have the error message stack smashing attack sir suppose we keep static space to each function in a program stack then can we prevent from this attack if we keep static space what do you mean by static space that means suppose fix space during main function we call that serve function so suppose we are locate some static space to only that serve function that means suppose 100 bytes in stack then can we prevent from this you mean static space to each subroutine yeah typically the amount of stack space the size of the stack frame to a subroutine would vary for because of different things one is the size of each of those arguments that is passed to that function one is the automatic variables so in general some for some subroutines the stack will be small some it will be much larger and so on so in general you cannot do that so that's the thing that's where the knobs come in the picture see in this particular attack what you're doing is the return address points to if you see all those that entire string the attack string the end of the attack string is the return address so that return address is supposed to start supposed to point to the beginning of the string but there might be some alignment problems and so on and so forth I'm not very sure that that address is exactly the correct address or it's off by four or off by eight and so on you know these things have an alignment problem they many of these variables that are pushed on the stack align at 8 bit 8 byte boundaries or 4 byte boundaries and so on because of this it might be off by 4 or by 8 and so on that is why I point to a safe place I'm not very sure you know where the thing actually begins the code actually begins so that is why I point to a bunch of no ops and the code will follow those no ops in case of canary value can we overflow the buffer in such a manner that canary value is retained very interesting question what is the answer to that so the question again is can we overflow the buffer in such a way that the canary value is retained if you could then the attacker would be very happy can you do that if you know it in advance the canary value that's exactly why I said that the canary value is a random value I as a worm writer don't know what that value is it could be five six nine three four seven six today it could be something completely different tomorrow and so on and so forth and also the other see a lot of different things are happening out here so the canary value so when you override that buffer the buffer grows in this direction which is in the opposite direction to the stack so you are bound to overwrite that on the way to the return address on the way to the return address there is that canary value so you will overwrite the frame pointer you'll override the return address and of course as you can see the canary is before that so you will override the canary value so there is no way to retain that value unless I could guess it we know the position of canary value right yeah so we can bypass it right when if we know the how to bypass just think about what you said how to bypass it when I start to overflow this buffer I obviously start populating the buffer from the start of the buffer whenever I do a string copy into this buffer it starts at this point right because memory is growing in the opposite direction the stack is growing upwards the memory is growing downwards in this picture so I start to populate in this direction on and on and on and it has to go one after the other that's the way addresses are arranged over here and then the next thing I do is this canary value is overwritten then this is overwritten because I have to override the return address there's no option that is one of the main funders in this overwriting overwriting the return address so the canary value has to be overwritten so in the afternoon session we are going to look at some tools like nmap and nessus and snot I just wanted to get a feel for how many people in the audience knows at least one of these three tools or is at least as use them in some form or the other please raise your hand how many people have used them in some form or the other so I think this is one of the important things that you should take off from this course because that's very much a part of security is how to install these tools and how to use them and how to make your students use them so we cannot actually have you use them in the lab because these tools generate a great deal of traffic and there are 250 participants the network will go down so what we're going to do is we're going to have demos of each of these three things today and a demo of metasploit tomorrow so metasploit is a framework for figuring out what are the vulnerabilities and even exploiting the vulnerabilities that's why it's called metasploit so stay tuned for this and when you go back to your centers and in July when you host 50 other people please make sure that all of them go back to their colleges able to install you know nmap and nessus and snot and so on and make sure their students learn to use some of these things that's an important part of the lab for this course and of course via shark okay if there are no more questions I think we'll break over here for lunch