[COURSE_PTHE] 18. 缓冲区溢出

1. 缓冲区溢出(Buffer Overflows)

    This lesson is a start through impact assessment of what happens in a buffer overflow. You'll write a basic C program to help you grasp this concept.

    The Buffer Overflows module explores what it it means to think like a programmer and how the device manages resource space issues.

    The topics explored in the Buffer Overflows module include:

  • Whiteboard, which shows the interrelationship of all the basic components you must master for this module
  • And the following simulation labs:
    • Make, Compile, Run Lab
    • Stack Lab

    Hi Leo Dregier here In this module I want to talk about buffer overflows. Now we are going to need to start thinking like machine language, a computer because this is how does a computer store things in its memory and how can we manipulate that process. Now it is basically pretty simply I want you to imagine an ice cube tray, right. This is a modular framework so if you put too much water into one cube, the water flows into another. Well memory sort of behaves in the same thing. But every ice cube is its own application or its own space. So that is the basics now we are going to cover some of the different tools and techniques that you can use and also cover the different types of threats and the different types of software which we can use. But this is a specialized field of study because you realistically now – now you really have to think like a programmer in the sense. So let us go ahead and get started – let us talk about buffer overflows.
 

2. 框架

    This whiteboard lecture explores how to manage an overflow in your programs application space.

    Since all applications experience buffer overflow eventually, penetration testers most know what’s going on with their software applications in order to recognize any unusual behavior.

    In this module let us talk a little bit about buffer overflows. Now to make the case here I want you to think about memory like ice cube tray. What happens if you put too much water into a particular cube that overflows into another cube. Well each cube is a separate application or separate memory space. By manipulating one cube you overflow and manipulate the integrity of another application. So let us take a little bit closer look at some basic concepts of overflow. Well we just talked about the analogy of ice cube tray what you can do is put a boundary check on what gets stored in memory and if you actually set the boundaries then you actually decrease the likelihood of actually overflowing into another section of memory. You have to watch to watch your commands like string copy because this is where we say. Go get something, copy it and put it somewhere else and remove the memory around in terms of heaps and stacks. Also you have got programming vulnerabilities in themselves. So whether you are using c or c++ or whatever the programming language is there are certain vulnerabilities within the way that the programming languages work within themselves. So just knowing that you can use better programming languages that would actually achieve the objective. That is ultimately going to be the better route also security guys are not necessarily programmers and programmers aren’t necessarily security guys. More so very few are security people or programs are actually pen testers. So this is definitely a specialized field of penetration testing. You typically can break pen testers down in the basic areas like network pen testers or programming pen testers or wireless pen testers where these security pen testers or software pen testers are definitely unique. Plus you should also understand stacks – the concepts like last in first out or first in first out. This is the way that memory gets stored. So if you understand that well then you can manipulate an application to take advantage of that. Next keeps this is your dynamic memory and we can use code like I caught malicious location but it is actually memory allocation but if it is done wrong well then it could be a malicious location. But it is how do things dynamically get stored in RAM for example let us say an application. You put some input or some data into a field that has to temporarily store that memory. Well it is going to use the heat portion to dynamically allocate that. Also the concepts of pushing and popping. The best example of push and pop that I ever heard is basically if you have ever been to a MacDonalds or something like that where they have the stack of cups. This also gets tied into the last in first out – you take that stack of cups and you basically slide it in. So the last one in is basically the first one out and that is how memory can get stored into the stack in terms of pushing and popping. Also you can use the analogy of the champagne bottle you push it in and pop it out. Otherwise you can do that but if you look at some of the tools we would definitely pay close attention to the extended information pointer. The stack pointer and the base pointer because this is where the programming languages get their next instruction set as they actually process the code. Also we talked basically before about shell code or even polymorphic shell code – in the concept of programming languages. Shell code is code that is specifically relates to an exploit. So as you send the shell code over to get to executed. If it changes the stack or performs a specific exploit like a buffer overflow then that shell code can also be malicious. Then you have no operators or sometimes these are called – no ops or noops even depending on how it is written. It is written in a ton of different ways but nop should work just fine for our purposes. And hex you could go the 0X-90 but is basically. No operator or filling the stock with almost to bypass the instruction set. Therefore manipulating where the next instruction set actually comes in and then there is also the concept of smashing the stack which is just layman terms for creating a buffer overflow. So we look at some of the hands on examples. We are going to look at tools like ali and heap.exe and things like that. There was a handful of tools here that we could use to get the basic idea of how to manipulate memory and buffers and some programming language compiler techniques. How to get information out of executables like bin.txt and things like that. So we are looking at a handful of tools but realistically like I said this is on its own field. So basically let us look at some counter measures what would you do to stop the penetration tester. Again this is high level so one thing I would highly recommend is actually manually check the code in itself and typically we try to rush things to the market. So your programmers develop stuff but they don’t necessarily look at the security aspects of that. So there is no really, really good manual auditing of the code. You may have heard what the developers say. Hey great works – where will you really hear developer go – hey great that is secure. They think in terms of functionality, not necessarily security. So when you manually audit the code. Also do it for security not just functionality, use good compilers or safe compilers. Safer library support depending on what programming language you are using. Disabled stack execution if at all possible – you run time checking. So that when the application runs it gets checked. Design the application with security in mind not just functionality – you could use things like stack guards which act as the executable is running. It detects like a buffer overflow and therefore stops or prevents it. It is kind of like a intrusion prevention software for executables if you will also restrict certain components of code or certain uses of it like gets a string copy or malloc or whatever the programming objective you are trying to achieve. There are certain things that you should restrict from using more so than others or at least put a boundary check on them and then if you are from the windows LAN. You could use something like data execution or prevention which is really just a turn on or a turn off component. So in this module we talk about the basics of buffer overflows and we will talk about some tools and how to analyze this. We use some stack analysis tools and we will use – and we will get the basics. But this is definitely its own field outside of the scope of traditional network penetration testing where we focus on scanning and ports and exploits and wireless and things like that. So let us go ahead and take a look at some hands on examples.

 

3. 配置、编译、执行

    This lab demonstration video takes you through the basics of writing a standard “C” program, compiling and then executing it.  The demonstration uses a straightforward Print Statement to show you the basic fundamentals of writing a C program.

    Hi Leo Dregier here. I want to talk to you about writing a basic c program, compiling it and executing it. We are going to take a very simple approach we are just going to do a simple print statement but I want to kind of take the mystery of how to write a basic c program. So if you are through with c programming you may want to skip this video or continuing watching it for accuracy. But basically what we are going to do is we are going to go to our desktop inside or our Kali Linux image. We are going to right click – so new document and just select a new empty document. You call this whatever you want – typically it would be the name of your program. So we will do Cybrary.c is the name of the program and you can see it changes its icons a little bit different it we were to change it to something and rename it to something like TST. You know it will change the file extension but we can go ahead and leave it as a .c but this is again un-compiled code at this point. So go ahead and open the file up – you can double click it or edit the file or open with any basically any editor that you need will be fine. So the first thing that you want to do is basically include some of the header file information and to do that – let us do that again. So what we are going to do is basically include some of the – header information. Now these are good to have because they basically c code exactly where to start and what to reference and it really depends on what compiler you are using. But it is – just a practice to have any sort of programming. So the pound sign is going to be common these are going to stripped out when you are trying to compile your code or should anyway but then again it probably depends on a compiler. So we are going to go ahead and do a pound statement which is common and we are going to include with a bracket a standard input and output.h file and we basically just do a stdio .h and then include that with a less sign and a greater sign stop brackets. Not to be confused with some of the other brackets that are available. But nonetheless these are the header files – these are also part of the preprocessors which are used when you are actually compile your code. So the common ones that you want to start getting a practice or would be the standard input and output and the standard libraries. So go ahead and install which two comments includes http:lib.h now there is a little bit of a variance if you are going to use single quotes or less than a greater than signs. It just depends if things are already in your path or already not in your path. We are not going to cover that here but just wanted to make a quick reference of it. So it is basically standard input and output standard library header file. Then we can go into just writing some basic code so we can do initialization, name and then go ahead and do two brackets and notice they highlight here start and stop. Let us hope for the reference to make sure you don’t have an extra bracket somewhere. So then we are going to add in another bracket and then we are going to do a print statement. So we are going to go printf, open the bracket and we are going to do cybrary.it is cool\’ and then go ahead and end that and then and you notice that they highlight start to stop that is make sure yet again. You are consistent and then go ahead and add a ; to the end of that and then hit enter. Do a return – 0[]; and then go ahead and finish the statement which you notice get highlighted as well here and here. I mean that is the basic code and this is as basic as it is going to get. Because all we are doing is basically we are going to compile this code and we execute it. It is going to print the statements of term outside that ips school and then they go. So pretty basic, pretty straightforward. So go ahead and then click file and then save and then open up a terminal and if you do a print working directory of c and the root. So we are going to change directory to desktop. So that way we can actually see that our source code or cybrary.c is actually available and then we are going to go and get an installer. Now calli linux has the gcc compiler already located in it and you can prove this by doing a locate gcity. If you get a whole bunch of stuff back like I did – clearly you have something – you have not found them means. You don’t have it – so I am going to scroll back up and going to make some sense for you. So here we go – locate gcc so the first thing we see here is basically some opt firmware and we can go ahead and skip these but you can see things like make file cc and things like that. We are going to scroll down user bin there is lots of gcc and bin directory or the binary directory they have lots of libraries support. So that is a good sign as well – again you would not see any of this if gc was not installed on your system. No matter what system you would be using. So and then of course a whole bunch of de package information which is where lot of the libraries are kept and you can see a bar library. So no less improving here is that gcc is installed. Now if I clear the screen then I want to actually install this we could do a pseudo apt get installed build – essentials and I am going to do this with a pseudo command and I am already locked in this room and I am going to spell it correctly. Build essential and I am going to spell install correctly and you can see that it would go out and look for it and it will say build.essential – this is another way that you could check but if there wasn’t then by typing this command apt -get install build -essential that would install the necessary compilers, unnecessarily. So if you are not on this particular UNIX or Linux build you could certainly add it to your system relatively easily. Install is painless takes five seconds – you can go ahead and run that. So we will clear the screen now let us go into compiling our simple program. So if I list what is in here you can see that I have a cybrary.c – so we are going to do a gcc or enter the name of our source code. So it is cybrary.c and then our output which is whatever the name of the executable that you want us to be named. We will just do it – we will be simple and choosy here. We call it Cybrary and if you don’t get any errors – things went pretty well. So that is it we have written some code – we have just compiled some code. Pretty simple next part we could actually run the code. So do a ./ and then the name of your program and hit enter. cybrary.it is cool which is the print statement that we had in our document and that is the absolute basics to one getting some c code in a file. Again very, very simple you can build upon this – next you can start putting in memory allocation and start setting parameters or start manipulating this file and build upon it. Which we will do in subsequent videos to try to get it to do something cooler than printing something to the terminal. So what we have done is written some c code and compiled it and then executed it and you can see it was relatively easy to do. So a little knowledge on c programming – you can certainly easily just create some generic code. Now when the next couple of videos will start looking at input statements and memory allocations and things like that and start looking at how basically make this program do bad stuff. So that is it my name is Leo Dregier – thank you for watching and don’t forget to check us out on Facebook or LinkedIn YouTube and Twitter.

 

4. stack栈

    This lab demonstrates the basic process of a buffer overflow from start to impact, including testing and evaluation in a simple C Program.

    Hi Leo Dregier here. I want to talk to you guys about buffer overflows and how you can one learn about the basic processes of buffer overflows. I want to take you pass some of the theory and show you some of the hands on testing and evaluating buffer overflows. So basically what we are going to do is look at a stack based buffer over flow that I have written in c programming. So I open up the document here and I just want to explain this to you that way. You can follow along and try to reproduce this on your own. This is definitely going to be a monkey see, monkey do type of lab. Give me one second here and I am trying to resize the text here. Let us do – it starts with talk about the basics first. You basically have the first section here and then the second section down here. So the first section is in main closed parentheses in arguments c, character Asterix argument value and whatever that is and parenthesis and then bracket. So if the argument that can’t be less than two characters basically print a statement. You need a value and then exit out otherwise if we do – it is going to basically copy that and then basically print the statement. The value is whatever which is actually listed down here. So we are basically supplying that value and then printing that value and then you can see that there is a string copy of the buffer overflow and then the arguments from the previous value up here. We set the buffer here to ten characters and so we are going to prove here is that what we are going through here. Just because we choose something beyond ten characters – doesn’t realistically mean that the program is going to crash or bad stuff is going to happen and in many cases programs buffer overflow all the time and they work just fine. So it is only in certain instances where you get a lot of buffer overflow that the program actually crashes. So when we compile this and execute it. You are going to through a series of commands we are going to use the GDB. We are going to go through and we are going to look at the compiling this in GDB and you can see actually how this works and I will show you some of the variables that you can use to actually see this run. So nonetheless it is a very, very basic program clearly these could be pages long but that is okay. Let us go ahead and open up a terminal and the first thing we are going to do here is basically compile this number. Compile I will show you the syntax any way – you want to follow all – so what I am going to do is do a gcc. The name of our source code which in this case minus stack.c and we are going to do this with the dggb compiler switch and what that does is that allows us to kind of set some of the break points inside of the program as opposed to actually putting them in the source code which is actually helpful and then you can set your output file to whatever you want to call this and since I have already have this card stack.c you could do it whatever output name you want. Whatever you want to execute or refer to this file as so. Stack.c is what I did before just to share that this works. I am going to do stack one – so if we get an error here. Then you can basically see start trouble shooting, so in this case if you look at the working directory I am not actually in the right directory. So let us go ahead and change directories to – in this case I am working in desktop. We just want to run the command again because that should be where the name it is – and it compiles and it gives us information and in function main, morning. Implicit declaration of built in functions string copies. Enabled by the full however it is just a warning – so it should still be and execute just fine. But nonetheless you will realistically be looking for error messages here. If you get an error message then things went bad for example if I take out my end bracket here and this piece here. You will see that it will basically be error or if I put too many brackets in or something like that. Let us go ahead and save the set as stack two and then I will show basically what an error message looks like. So in this case same exact thing – stack two and let us call this stack two and boom there you go. Now we have got the error message expected declaration or statement of value. Now most of the time when you are compiling c code or writing c code. Then it acts at at time it is going to be a syntax error somewhere in extra declaration too many, too little. Go ahead and look at syntax and trouble shoot that first because if doesn’t work don’t freak out. It is all part of my learning experience think of it as hide and seek for errors and that is the way you want to approach this. Don’t get frustrated – don’t want to give up – continue through because this is very much a problem solver. I did that once without an error just a couple of warning and then I created an error just so you can see what syntax look like if happen to this wrong the first time itself. So let us next us go ahead and another way we have actually got this ran and we got it compiled. Let us go into gdb and you are going to want to run this basically like you would any other program. So I am going to run stack which is the name of my program and you can see copyright information here at the top. This gdb was configured as i46 linux. Now what one thing to do here is make things easier for your eyes and to illustrate to basically to put this in easy syntax. So you can actually read it like a human is going to go ahead and set the dis-assembly flavor to intel and you basically do that by declaring, set disassembly-f and then you can tab your way through for flavor and set it to intel and if you come back no problems should be there and then go ahead and you can type list and list is a hopeful command to know when we are using this because it starts showing you what you are source code look like and you can use that especially when you start getting into break points and deleting breakpoints and things like that. Because you can test this out by declaring this – now again I want to back up to what I did in the beginning when I actually compiled this I compiled this with the -ggdb switch that allows me to set the break points now that I am actually inside this program as opposed to having it in the compiled code. So we set the disability flavor then we listed out the contents of the source code which we can see here but let us go ahead and run this. Now to run this we basically can – basically do a false statement and you can do this by basically typing run the program. $ sign [perm.execute single tick print a which is the value that we want to print into the product copy into our buffers. Time this ten send me coal and single tick and the parenthesis and see what it looks like and you can see starting the program the location which we ran the program. $pearl print a ten times and if count that up there should be ten and you can say that the program accepted that and fine. Great – let us basically buffer overflow this – let us use the value of eleven. You can see the range is fine I am not going to increment this by once. So let us do twenty – so let us put twenty a’s in there. You can see the program still work fine. If we do 25 we get a fault and I am just going to auto program some values in here. So if I do like 50 start it from the beginning you can still get a whole bunch of 50 a’s in this point and you can also see that it is actually stating the memory register here and we are going to come to this in a second but 401 401 401 this is all a – you can actually prove that. If you were to change it to for example b’s start to program from the beginning 401 401 and 402 402 a b you want to get creative here and this is how you learn. This is how you learn the stuff – start off from the beginning again and you can see that it is 403. If I wanted to see what the value of ten is – it starts from the beginning there you go. That is 30, 31 or 1010 so we are going to back to a’s just for the simplicity and again there it works. So now what we are going is we are basically supplying value to the executable it is copying it to the buffers and it is basically buffer overflow. Now there is not a convenient way to l look at what is actually happening to your buffers at this time. So in order to do that we basically have to look at the buffers. So let us do an x/ 20xw and let us look at the extended stack pointer. So basically simply doing or reacting to print where it is in the stack. Now this is going to be helpful and I can change this. If I want to change from 20 to 40 or 400 or whatever I want. I can print as much or as little of the buffer as I want. Twenty is fine – but basically we would be looking directly right in here. Right in the section here because you can see all the 401 401 401 all the way through here. So if I change this – if I go back to print 500 a’s to the buffer start to program from the beginning have it air up and then go look at the buffers and let us look at the first 500 characters. You can see that now my buffer is all 401 401 401 401 so I am actually proving that the buffer is doing in fact get over written at the different memory locations as here on the left. So it is nothing but overflowed buffers at this point and I hit enter a few times and you can actually see where that ends and then it picks up other values at the end of that and so what I am proving here is that the buffers are in fact getting overflowed. Let us go ahead and listen things out here. I want to show you guys a couple of more things here before you wrap it up. I want to show you how to set break points in here. So we go back to our program you can see that we have got and you could do this with a list command earlier but basically it is right in here. So if you want to look at this right before the buffer gets copied and check the buffers and check the stack foyers and then let the buffer overflow happen and then check the buffers again and kind of look at that just one line at a time and you can do that. A couple of different ways you could do that – you could actually count the lines down like this or 1,2,3,4,5,6,7,8,9,10 so it is right around nine and ten is where we want to set break points again and this is the value of actually compiling this with doing a -ggdb because I can set the break point to nine and it says break point to nine and it says break point ten set and I would set another one. Now if I run the code it will execute it 0:14:24and I am going to change this back to ten but it will basically break right at the nine and allow you to basically look. So it has ran the program copied the ten a’s and then break here for me to see and then I can look at the first 40 of the extended stack pointer. So if I look at that here you can see basically the buffers look fine. I mean I get all sorts of stuff in here. So nothing really to see and then if I change this again and let us go back to 500 and start from the beginning and then look at the values in here and we will just look at the first 40. If I look at the first break point before the buffer happens – I am proving that the buffers look absolutely fine. Just a bunch of random stuff I don’t see – no operators. I don’t see your repeated values from the string that I copied which is why I wanted to do like all a’s or 1 & 0’s just to make it completely obvious – no operator 0x90 just look at that pattern all the way through. You want to make this obvious when you want to learn this – you can actually distinguish what normal buffers look like versus complex buffers and then you can go through and actually see more of what it looks like and if you want to delete the break points and remove them completely. You can actually just put a delete and then delete all the break points, yes. That will get those to go away and then run the command again from the beginning and then check your registers now buffers are overflowed. So that is the absolute basics to doing a buffer overflow. Now we haven’t looked at exactly how this gets exploited. What is being disclosed – what code is being arbitrarily executed. How they are crashing the system – what memory is it taking? What is task manager or top look like. So if I just give you an example here – if I am going to look at the top – you know what does that look like. These are all things that you could at in the grand scheme of things to really understand what your buffers are doing on your system. So that is a summary, just to give you one summary real quick we basically took some buffers copied them, printed them, we compiled the program using the -ggdb we ran the program gdb ./ then the name of your program. We set the disassembly flavor to intel, we listed the code, we looked the code we ran a basic pearl statement to basically just supply input to the program. We looked at the different stacks pointers showed you how to change the stack pointers with x/20xw or 500 if you want to look at the first 500 and things like that. Very, very basic – very, very easy way. Now that you have seen this the key to actually making this makes sense is it go ahead and reproduce this make your own errors and work through these and get through these on your own and then you will start having a better understanding of how buffer overflow works and then hey at the end of the day. If you want to tell your friends and family. I created the buffer overflow and then you can say I actually do it but if you cannot do this and you don’t know how to do this. There are lots of hackers out there that do not know how to write a buffer overflow and I have just clearly proven that it is not that hard. So I want you guys to practice and I want you guys to understand this and if you have any problems with the video. Why don’t you send me a link on the contact me section and answer any questions you have about buffer overflows. My name is Leo Dregier thanks for watching – don’t forget to check me out on Facebook LinkedIn YouTube and twitter. Also by now you should be well familiar with the Cybrary.it website be sure that you are sharing, connecting because that is how you move up in the application. Use it, learn from it share it and take it for all it is worth because that is why it is here.

 

posted @ 2015-09-30 22:28  It's_Lee  阅读(123)  评论(0编辑  收藏  举报