 The microphone is not on. Awesome. It is on. That's weird. Okay. I'm sure there is some, so I'll take questions on Assignment 3. No questions? Maybe I'll pull up the... What was the bug? No. What was the bug with Level 2? There was no bug. Yeah, I thought you said something else. I said it's working as intended. I made no changes. We asked, but there was no bug. Yes, exactly. We're not quite sure how we did something, and there's no way to replay it, because you have to log off to know that you made it to the next group. Right? How do you want us to handle that in the reading? Yes. Yes, that's what you did. We'll figure something out. There's a way I can set it up where you're a member of all the other groups. I'll look at it some more, but yeah, you should know how you broke something, right? I mean, you did it, so how did you do it? Well, the problem might have been related to that not getting feedback on the input necessarily, so I wasn't getting feedback on it, so when it happened, I had no idea that it happened. I had no feedback to know that it happened, I think because of the piping and stuff. Should at least have it be man-history? Should at least have it be man-history? Oh, that's true. I remember what I did. All the different steps, sure, but I had no idea which one was actually successful because I got no feedback when it happened. And so I kept going and then happened to run and score and see that I was... I bet you already broke it. Interesting. Yes, I mean, you know, so yeah, can you go to score, definitely, and tell you that you broke it, right? That'll tell you. Yeah, maybe I can give you access to the levels or back levels or something at some point, so that should be fine. Cool, okay. Any other questions? GDB shows us a mutation point for everyone. GDB shows us a mutation point for level one. That's weird. Actually, you said the same thing, right? That is strange. Okay, so because you can't GDB instead to ID program, it should drop, regardless of what it is. One thing you can do, if you have access to the binary, you can copy it from there to your local home directory, so you should be able to run GDB on it then, unless there's something wrong with the server. It could be because I changed the file system so that you only have access to your programs. Actually, if I could move it, if you GDB part two, that's weird. Okay, yeah, I would say copy it, you can copy it either to your local folder, it should definitely work then, if it doesn't, then send me an email, because I don't know, I don't have any reason why it shouldn't work, but it's not like extra hard in that sense. It's not intended to be like that. Okay, so in case you didn't see it, I wrote out these are some tools you should use, if you find other tools helpful, send them to me and I will add them to this list. So basically, the main idea is you need to first do some, you need to understand how the application works. So a very highly unaffected strategy will just be throwing all the techniques we talked about at trying, but for overflows and train injections, all that stuff, because you don't know how the application actually works. So you need to understand how does this application work and then understand what could be the possible attacks to get it to do what you want to do based on the attacks that we talked about in class. So there's pretty much two ways to go about doing this. So the first way is statically looking at the binary to see what it does. So that would be using ObjectDump or using one of the other disassemblers that we talked about in class in order to look at the binary, understand from the code what is it doing. Has anybody tried that yet? How was it? Difficult? Because of the x86 code? Yeah, so it takes a little while to get kind of used to that. So that's definitely one thing to do. I think it's good just to look at it and kind of see what's going on. You can also see, usually from ObjectDump, depending on how the application is compiled, you can see what library functions it holds so that can help tell you maybe what's vulnerable. So what about, so why do you use GDB? So what's the other strategy? Why do you use GDB? Instead of just looking at the program as instructions as itself, you want to actually understand how is this program executed. So with GDB, you can debug the program and then you can set breakpoints, you can see what it's doing, you can output the value of registers, you can do all sorts of stuff. So can you just use GDB to break the program? No? Yes? Why? I think you can because you can save the values. Yes, you can arbitrate it. Once you're GDBing a program, you can arbitrate it to change the values. So let's say you change the memory that you want to do, is it going to work for this thing? That would be a huge security vulnerability if you could just debug a setUID program and then automatically get root privileges. So part of what, when you can GDB a program, maybe that's why it crashes. Yeah, I don't know. I've got to think about that. To debug a process, you're using the Ptrace interface and so the operating system, if it sees that you're trying to debug a setUID program, which in this case you are, so it's executing a few. So in that way, even if you break it, you have full control over it, but at that point it doesn't have the privileges that it normally had. So GDB is definitely important. What are some other, any other tools that we use so far? Strings? Actually that's a great tool. What do strings do? Neatly print all the strings. Yeah, so actually what it does, it's actually an incredibly simple tool. It just looks through, not even a binary, just any data or any bytes. And it looks for ASCII sequences of at least, it's configurable, but it's at least four. And it will output all of those that it finds. So if you run the strings command on a program, let's have no idea it was going to work. So I'm at level three on this thing. So if I run, well, let's say if I, what's some program, let's say Python. So if I run strings on user, then Python, it's going to output all of the ASCII characters. So you can see some of them are garbage, right, DKB, AppSign, right? This is probably just randomly some characters happen to be ASCII strings. But it does show me interesting things like all these .so, so I can see what libraries this program is using. It shows me the actual string names of some of the functions that it's using. The libc functions, memcopy, malloc, all kinds of stuff. And we can maybe even see, and then it has all of these Python symbols in there, which could be interesting. So yeah, it's usually very nice. I mean, obviously Python is a huge program, right? So, but this is nice to see. You can see what strings are in the program, right? So I know if you're interacting with it, have you seen all of the programs? Are there some error codes that you're not seeing that could be interesting? Right, so this is part of kind of doing the static analysis to see, hey, can I actually can I understand what this program is doing? So strings is incredibly useful and really simple. What else? Any other tools? Object up. Object up? Yeah. So what you may want to do, I'm going to keep using Python just so that there's no spoilers. Right? So as we saw, we can use object dump to oops, that's because I don't know. Oops. Yeah, so I can look at the code here, right? See, it doesn't have a main function. It's really interesting. I've never looked at it. Yeah, so see, even Python has a main function, right? So you can see that it's doing stuff. So yeah, we can look at actually the Python interpreters code, so that can help to understand the control flow. See what else? What are some other things? Hex dump, ooh, hex dump. What do you use hex dump for? It's just easier to look for the file in front of the strings. What do I do? We'll just go with this. So you can use hex dump and this will output the actual ASCII, like the hex of the file in ASCII which could be useful. ASCII will output on the right the strings in there so you can see where exactly those strings are so you can kind of look through it. Python is a bit... strings is actually a little bit better for this. Yeah, you can see all the things in here. Anything else? S-trace. S-trace, so what's S-trace? This is the... I guess it's kind of big picture of library calls and stuff. Almost, almost. So it's not... It is library calls in the sense that it's the system calls so the S-trace stands for system so this will trace all of the... all of the system calls that this program is making to the kernel so it essentially puts some hooks in there and shows you exactly what it's doing and this can be incredibly useful to understand what the programs are doing. So for instance, if I wanted to say what is Python actually doing and there'll be a lot of output so... Okay, cool. Do you want to set a reset to an enter to if your terminal ever gets messed up? It's a good handy trick. Okay, so... I think I can do... So I'm going to give it a file or I'm going to give it just a lot so it'll pull the mess up. So you can see through here, these are all remember the system calls at the kernel level so these are all the calls into the kernel that this code is making and so... let's... actually you can see really interesting thing it must output it to... okay, yes but it outputs it to standard error so piping it to a mess doesn't really help I guess I could have done it to Python but... So we're saying that Bash actually has an exec Python and if we look at the exec ve function we see that it passes the list of arguments and then the environment so we see that it's actually calling it invoking it with user bin Python and then the parameter lop and so this shows us actually all the system calls is making and so to do this we can actually see that the OS is even it's loading all this stuff it's actually reading in the Python file like this l file so this is kind of normal stuff that should be happening and then and it's reading some files so we can see that it's trying to... yeah, so it's reading all these things in it's registering a bunch of signals so we can see that these are the signals of the Python program I'm just going to kind of go through this if I look for the lop so this could be a lot of information and not all of it's actually important but it's kind of useful to go through because I can see that it's calling read link on the lop right, the lop is the parameter that I typed into the program it's getting the current working directory it's trying to lstat the lop and it's trying to open the lop and we can see that the result from the program from Python is that there's no such file directory and then it's writing out to the console so what does this tell me about the program what is it doing with my input the first argument yeah, not even a binary it's just trying to open this file that I gave on the parameter so now I know that this program is going to open whatever parameter I pass in so I can see here that the case that I tried is a file that doesn't exist so what case should I try next a file that doesn't exist exactly, yeah, that's what I was trying to do to try to see more behavior of this program cool so strace is very awesome strace s for system calls what's the other tracing program ltrace so what does the ltrace do so ltrace is library calls so ltrace will trace all the libc calls that your program makes so these aren't the calls that go into the kernel necessarily these are at a higher level so we can see, run it with ltrace to see what happens see sometimes they can be more or less or alright, cool okay, that was fun right, so as we'll see every library call that it's making is being logged I guess I can just kill it and see so we see that it's actually an environment variable so it's actually kind of cool we can already see that we can maybe alter the behavior of this program by changing these environment variables which is something we couldn't see from strace but we can see it here in ltrace because getenv is a libc call and we can see that in malloc stuff it uses semaphores it's calculating string lengths and it's copying strings around and we can see it's copying a lot of strings around I think that's mostly what it's doing I guess you can use ltrace to filter out certain things about what it's going to trace or not trace wow, this is like a lot of it's trying to parse the file it's trying to run it at the same time but I gave it a file that doesn't exist so this is I don't even know what it's doing it must be creating some yeah, something or maybe it's reading something or something anybody do research on the python interpreter? not yet cool, interesting oh it is, I was reading all the library files like all of the python library files interesting alright, so with these tools you can get very far because these let you see what the program is doing right, and so from there that can help you try to understand what's going on but using these you should also try to understand and know what you're what you're doing so keep track of the things that you're trying to read okay so we saw how we saw how the stack works and we saw how the stack changes when we make function calls and so stack overflows can occur when we're copying data when data is copied without checking the boundaries of that data because the programmer has to specify exactly how big chunks of memory are, arrays are so when we declare an array in C you have to specify exactly how many bytes or the size of that array and when we malloc data we also have to specify exactly the size and so the attacker can overflow what we're copying from or controls the length or size of what we're copying then they can force more data into, they can force larger data into a buffer that's a smaller size so normally so has anybody ever gotten a stack fault because they did something like this and they had a small buffer nobody can actually raise their hand okay cool so normally this causes a stack fault so kind of as a security person a stack fault should very highly focus your attention because usually depending on how the segmentation call is happening you can actually turn it into something, an attack or it's usually indication of vulnerability that you can use to exploit the program so if you usually if you carefully craft the buffer that you're overflowing it can as we'll see in this example you can try to overwrite that return value on the stack to save VIP so that way instead of that program going to where it was originally going to go to the function that called it it's actually going to go to somewhere you control where the control flow of the application goes you can make it execute your own code and so that's really this is more exploitation you can put this code that you're going to execute can be either part of the thing that you're overflowing or not it can be somewhere else as long as you can get the control to that program and this is why this is so important is this control now you're inside this process you are executing your code of your choosing in this process and so that code has the same privileges of that process so it's a setUID program you're going to have the privileges of that setUID so let's look at an example so because of the Cdeco calling convention the save base pointer and the save VIP are both stored on the stack so before we call the function we save the VIP with the call instruction and then the first thing that function does is save the base pointer and then set up a new base pointer so those are both on the stack so there's nothing in a program or a function so VIP and the VIP are saved on the stack so can the program read and write to the stack this is where it puts in its local variables it has to read and write to the stack if it didn't read and write to the stack then you could never use it so there's nothing that prevents a program from changing those values so we'll see what happens if those values are changed so let's look at an example so we have our C program we have a function called myCopy that takes in a character pointer this function has a buffer foo and we do a string copy from string to foo so what's this today it takes on a string copy to stir into the first argument we mean all the bytes from stir stir is a character pointer it actually goes character by character until it encounters the delimited character which is large 0 so it takes the first character that string points to right copy that byte copy that byte to the first byte of foo and then increment both by 1 and then keep doing that until foo points to an old byte so do we tell a string copy the size of the buffer foo no so if the attacker controls string controls the size of string can they make it this copy to be more than 4 bytes yeah right they can make it be however large they actually want to be and this is actually a key problem so string copy is inherently dangerous because we don't tell it the size of foo inside string copy because in C strings or buffers are just pointers to chunks of memory that have no length associated with them so string copy has absolutely no way to tell what the size of this character pointer that gets passed in is so it just stupidly copies from the source to the destination now the other important thing about string copy is it puts an old byte at the end may or may not be interesting so then we look at a main function that calls this so we're going to copy so you can see I used this for my class last year note to self never put in hard coded class information into strings in case you want to use this for other classes and then we're going to print something else and we're going to return 0 so pretty simple right let's see what happens when this program executes and how the stack looks based on this so when we do object down we can see the code of this application the x86 instructions and main in its apple prolog is going to first push evp then move the stack pointer to the base pointer so it's going to save the caller's base pointer it's going to create its own base pointer it's going to subtract ESP minus 10 or minus 16 then it's going to move this 8048504 onto ESP so where ESP currently is and it's going to call my copy so what do we know about this 8048504 what is this so is that that's not the string it's uh are these ascii values 04 is an ascii value 048504 08 the address exactly yes this is the address of the constant bytes string ASU space right so the compiler when it sees this constant string it creates an elf section for the I think it actually uses read-only memory for these constant strings so it creates a read-only memory segment and then it says in the elf header we looked at hey this constant string is at this specific address so I know in the code I can reference this address with this hard coded memory address and it knows because it created the elf file like this that it can use that exact memory location and the string will always be loaded there by the operating system cool then it's going to call my copy then it's going to move 8048517 to EAX it's going to move EAX into the stack pointer and it's going to call printf so what's the second address put the after yes the string after or the address of the string after and then we're going to move 0 into EAX call leave and then call return so what's this 0 into EAX doing the return value at setting the return value of main alright so then let's look at my copy so my copy what's the first thing the program has to do as to save the base pointer it's going to move the stack pointer to the base pointer it's going to subtract x28 from the stack pointer it's then going to move evp plus 8 into EAX then move EAX onto the stack plus 4 and then it's going to take evp minus c move that into EAX move EAX onto the stack so what's the stack layout going to look like this is what you should be thinking about is when we call a string copy what's the stack going to look like from these instructions so what's the thing that's currently on the stack at the stack pointer EAX and then what was in EAX going to trace it back so EAX is moving on the stack pointer then what's from EAX so remember the important thing about load effective address is even though as the parentheses there's no dereference here so it takes the value of evp it subtracts hex c from it so evp minus c then moves that into EAX so from evp what do we know about this thing that is currently on the stack before we call a string copy it's what it's it's the address of it's the address of it's the address of what my copy the address of my copy is going to be actually here where these bytes are stored right the call is actually going to be the one that pushes an obstruction pointer what was that what was that what was that right but we got just a second so there's a thing about it like this so the app ESP is here it's going to be plus four exactly so remember the calling convention says when we want to call something we push from right to left so the topmost thing on the stack is going to be the rightmost so we're going to push first the rightmost thing which is string and then we're going to push foo and then call and so for reading from the bottom up we go left to right so we know that foo right the address of foo and so what is foo where is foo located on the stack minus right to me the x28 bytes below the stack pointer that will be the that will be where that will be where the address of foo is but where is foo on the stack where is that value 0.2 0.2 0.2 minus 4 minus 12 minus 12 yeah so EVP minus 4 so this also helps this check so at EVP so we go down from EVP what are those variables those are parameters so let's think about before a function call in general from the CDEPL calling convention so we push arguments push push push then we call which pushes the instruction pointer and then the first thing we do is save the base pointer and then why do we do that subtraction we're making space for what for the local variables local variables so EVP is here I see so below EVP is what local variables so local variables exactly every time we see EVP minus something we know that that's a local variable and so when we see EVP plus something what's that? a parameter exactly and that's how you can read this so you can know so there's two tips that tell you that this is foo that foo is located at EVP minus C the first one is that it's being used here as the first parameter to string copy so you can trace it back and say okay this must be foo because it's the first parameter to string copy the other way is to say I know this is EVP minus something and there's only one local variable in the function my copy so this must be foo and then by the similar reason what's EVP plus 8 string str and then we leave and return after we call string copy it should be easy so you actually already got where everything is without even drawing the diagrams and stepping through it one by one to see how everything goes cool but let's do it so we can see how it goes okay so we have the only we have a bunch of registers right so the only registers used here are EAS stack pointer, base pointer, and instruction point we have all of our code here so the program is going to compile this and then we have our stack and so let's say our stack we start at FD2D4 and so that's what's in the stack pointer and the base pointer somewhere above that at FD2E0 and instruction pointer is currently at 804 4840E which is the start of the main function that's my clicker let's set through this right so let's say we're going to simulate the execution here and we're going to save the caller of main's base pointer so we're going to push EDP onto the stack and move the stack down so we have the save base pointer what's above that same base pointer? the parameter is past the main there will be the parameter past the main it's going to be above it what's directly above this EID or this starting this base pointer a number of arguments higher what was it? other programs other programs yes the return to save EIP the return address into the program that's called main so that's main is not any different just like every other program so there's the main we know that when we get called the thing on the stack right at that moment so right at that memory address I can't read it out FD24 what's at that location and that box that I didn't specify is the address of the next instruction that we need to return to from whoever called main so at the end of this main function when we call return that's where we're going to jump to and that's where execution is going to go to and then so we know so that's the save EIP from the last function our job is to save the base pointer the last function which we do then we set up our new base pointer for our frame so we say the current stack pointer is now the base pointer is currently our stack pointer where we are now that sets up the base pointer and then we make room for our local variable so we're going to move the stack pointer down and from this way from the base pointer which points here that's how we can get to argc and all the argv by going up so those will be evp plus at least 8 because we need 4 up there so the evp is here so 4 above that will get us to the save instruction pointer and 4 above that will get us to the first parameter which will be argc in main and then 4 above that is going to be argv so we subtracted we moved down the stack pointer is going down here at fb2 c0 now we're going to set up the stack for the function call to mycopy so we're going to move that hex 804 8504 into the stack pointer and then we're going to call mycopy so what does the call mycopy exactly like I'm going to do put this return address the address of the next line into the base pointer the base pointer is pointed up at the top stack pointer yes so it's going to push 80423 that's the next instruction we want to execute onto the stack and then what's going to happen this call instruction so it's going to save the evp and then it's going to change the evp to mycopy and actually I actually cheated a little bit here when you look at the assembly it's not going to say mycopy it doesn't have any labels it's actually going to say call 804 83 f4 so it's going to call that and so we'll have pushed 804 8423 so this is the address of the instruction directly after the call so remember maybe let's say right so these are the breadcrumbs so this breadcrumb here says okay when you're done executing go back to this address and start executing there so this is how the program can go make function calls and then you can come back picking up that bread to get to the correct functions cool now we need to do our so now mycopy is being called so it needs to save the base pointer because the current base pointer points up here to main's base pointer so we're going to save main's base pointer right now we're going to set up our own base pointer to set the new base pointer into right here of our frame and now I have to make more room so everything changes so now we're going to subtract 28 hex 28 from the stack pointer which I'm going to put it all the way down there and I also have a diagram here for the base pointer because it's currently at v8 so now we're going to move evp plus 8 into eax so what's evp plus 8 str right the parameter to mycopy and we know that A because it's offsetting a positive offset from evp and we know it's the first parameter because we know that 4 bytes above evp is the saved instruction pointer and 4 bytes above that is the first parameter to mycopy so we're going to move that into eax so that's going to move 804 80 8048504 hey that's not like 4 okay so then we're going to move that value onto esp plus 4 so that's going to be the current stack pointer plus 4 so that's going to be up here and then we're going to do this load effective address so we're going to calculate remember load effective address does not dereference anything where this dereference evp plus 8 well that's memory location fd2c0 we didn't move fd2c0 into eax we dereference that and we got whatever was at that value at that memory location which was 8048504 now we're going to calculate take the address whatever is in base pointer it doesn't matter that it's an address addresses are just values take fd2 wait sorry fd2b8 subtract c from it subtract 12 and move that into eax so now eax has the value fd2ac which is there so at runtime this address is going to change different runs of this program depending on the environment structure that can change the address of that constant string 8048504 is never going to change it's hard to put it into the program the stack can change this is why it's essentially calculating the address of foo at runtime so that buffer foo is located here and it's only 4 bytes the way I draw it it's just these 4 here so now we're going to move that value onto the stack pointer right to where the stack pointer currently is and now we've set up our function frame so that we can call string happy so then what is string happy going to do we take the return address put it in the stack pointer and then call the location where strs is located yes okay so actually because of dynamic loading it gets a little more complicated it has to look up and see do I have a string copy function have I loaded it yet if not able to dynamically load it and then put it in an address in the correct place so we won't go into that at all but if we just treat the function string copy as a black box what's it essentially going to do what was that right copy the byte at 804.8504 copy that byte to fd2ac and then increment both by one and so copy the byte at 804.8505 copy that to fd2ad d right copy those bytes into there and so then so we know that at 804.8504 are the continuous bytes exactly at this memory address is the byte A which is actually as the A which is what 61 65 okay 41 takes 41 no 41 is capital X oh yeah capital X doesn't matter but the point is that is what's actually that byte that is there is that represent that integer which when we interpret it as a character we interpret it as the character A and then one byte above that at 05 is going to be S and then one byte above that is going to be U and one byte above that is going to be space all the way to the end we'll get to the exclamation point and then a zero null light and so when we do this copy right this is exactly what's going to happen it's going to say take that A copy it as at fd2ac fd2ad take the U copy it all the way up so what's actually going to happen is ASU is going to be copied here into foo ASU space and so this is where we get into endian weirdness so you see we copy 61 73 75 20 but when we interpret fd2ac as an integer right so we copied it this way but when we interpret it as an integer we interpret it the most of the bytes as the highest one right exactly so when we interpret this as a number it's going to be hex 20 75 73 61 so definitely have to keep that in mind we're going to do a buffer overflow and then we're going to copy CSE space which is going to be the same thing 63 73 65 20 and then we're going to copy 340 space which is 33 34 30 20 just keep doing this there's nothing to stop the program from doing this because string copy doesn't know the length of foo it has absolutely no idea that it's copying over what was originally allocated to foo because it's just a pointer to some chunk of memory and we can increment pointers to get to the next element of that array so what's going to happen next without this piece without this piece without no space so it's going to be these ones and then it's going to overwrite this right space 201 and then it's going to write 5 space RO and then CKS and then what then the null byte right so does everything just crash and then this happens and then we get immediately a site fault after it copies this no why not because it doesn't know what was the return address it's just a set of data on the stack right remember we called it when our stack was located here right we called string copy here so string copy made its own stack space where it does all its own stuff and once it returns it's going to put the stack back here but we didn't mess with anything on here right we messed with essentially names saved things so string copy just returns and then now we get into we could do anything else right we still have our base pointer points to where it should be we still have our stack pointer points to where it should be right but now we have the leave instruction so what does the leave instruction do yeah so move ebp into the stack pointer and then pop ebp so it does the opposite of these two instructions so it's going to move the stack pointer the stack pointer to the base pointer so the base pointer is at b8 so it's going to change the stack to be at b8 and it's going to then so the base pointer we can see is the stack pointer is up there yeah bc oh oh oh because then we pop so it moves it here so what was here at fall the return value the base pointer the same base pointer this is this base pointer our base pointer currently points to the same base pointer at b8 so it moves the stack pointer to the base pointer which is at b8 and it pops that value it needs to pop that into ebp to restore the base pointer of main so it so now the base pointer is c6 c6 c6 c6 c6 1 6 6 so this is crash not yet right we're just copying one value from memory to a register right nothing back there now we return so what's going to happen what does return do now the previous value over the it's going to yeah so right here at the stack pointer right it's going to say return means essentially pop into eip so take the value that's currently at the stack pointer move that into the instruction pointer and start executing from there it's going to set the instruction pointer to be 31 30 32 20 and then the program is going to go fetch and start executing from 31 30 32 20 and that's where we get a segmentation fault and everything finally crashes because there is no memory mapped at 32 30 32 20 what if there was memory mapped there just just interpret fetch execute right just executing memory so we can actually if we compile this we can run it and we'll see that it outputs a segmentation fault now you will need more flies if you want to try this on a newer gcc this is on an older gcc so this doesn't have any of the stackenaries or any of the other detection things but you could do this and it works and this is a really key thing if you're trying to do these exploitations to verify that you've done it so getting a segment fault is one thing but you want to know why did it segment fault got you to control PIP got you to control something else it was another point of dereference so what you really want to do is load the program in gdb run the program and see where it crashes and why it crashes so it's going to tell you to start the program and then this is the key it says segmentation fault 31 30 32 20 where do these bytes come from well they're in the program that would be us so that means we can control the instruction pointer 100% so we can force this program to go wherever we want to go and execute whatever we want to execute and so if we look at the registers we can actually see that they're exactly what we calculated by hand running through it so we can see that the base pointer was 60 60 60 166 as we saw so we were completely controlling the base pointer and we're completely controlling the instruction pointer you'll have to disable the stackard and address randomization for this tool stackard you can still do this randomization doesn't matter we can do any hard coding anything we're still causing it to crash okay so these are the vulnerable functions that you should look at these are the functions that by themselves are inherently vulnerable because there's no way for the programmer to specify only copy this many bytes they're judged entirely on the size of the input so if the attacker can control the size of input they can always make it larger even the so on that previous example foo was only 4 bytes large but even if foo was 1000 bytes large or 10,000 bytes large if we control what's being copied there we can always make it bigger because at 10,000 is constant it doesn't depend on our input and string copy has no way of knowing that it should only fill 10,000 bytes in there so gets is one of the functions if you see this function you should immediately be thinking buffer and workflow but you've got to think how can I control the input to this but it has a caveat always look at the documentation for these functions so you know exactly the semantics for instance, forget you can't have any new lines or end of files so that's actually really important when you're trying to create an exploit to know what characters can I use and what characters can't I use as we saw string copy the same with string cap concatenate strings together sprintf so printf into a string and there's no way to specify the exact size there same with vsprintf scanf, sscanf and fscanf if you use the %s these are also wonderful and any custom input routines as well so you can have a program that calls getCar to get a character if it keeps doing that and puts it into a buffer with no bounds checking then you can control that so as long as you can control the input to these functions 9 times out of 10 can cause some kind of overflow that was awesome, cool so we'll stop here and we're going to get into on Monday how to actually exploit a stack overflow vulnerability