CompTIA CYSA+ CS0-002 – Mitigate Software Vulnerabilities and Attacks Part 2
2. Overflow Attacks (OBJ 1.7)
Overflow attacks. In this lesson, we’re going to talk about the three types of overflow attacks. This includes buffer overflows, heap overflows, and integer overflows. And as we go through, I’m going to explain a little bit about each one. Now, when I talk about a buffer overflow, this is an attack in which data goes to the boundary of the destination buffer, and then it begins to corrupt the adjacent memory and essentially it overflows. So if we’re talking about a buffer, what exactly is that? Well, essentially, any temporary storage area that a program is going to use to store data, this might be a variable or user created data. Now, the way I like to think about a buffer in a visual format is to think about a glass of water. Let’s say I have a glass and I put it on the table and it’s a 16 ounce glass. Well, that means how many ounces can it hold? 16oz.
If I try to put in 15oz, will it hold it? Yeah. If I try to put in 5oz, will it hold it? Yeah. If I try to put in 20oz, what’s going to happen? It’s going to overflow and it’s going to get a mess all over my table. Well, the same thing happens in memory. Your memory is set up to hold a certain amount of information. And when a program starts up, it allocates a certain amount of memory for its ability to store its stuff. And so if it says, I’m going to store 16oz and then you try to shove 20oz in there, it’s going to overflow into the adjacent memory cells. So think of it had three or four glasses sitting next to it, and the water would start filling those glasses. That’s the idea of a buffer overflow. Now, why are these so dangerous? Well, as we look back to the different data breaches that have occurred, over 85% of data breaches were caused initially by a buffer overflow attack.
And so this is a really dangerous area for us. Let me go ahead and give you another example of this that I use in my security plus courses. Let’s say I want to store your phone number. I pull out my cell phone and I want to type it in. Well, how does the phone number look? If you use an old phone number, it might look here in the United States, like seven digits. So I might have something like 555-1234. Now, let’s say I set up my buffer as an eight bit buffer because I was expecting seven digits. So I have an eight bit buffer and I’m going to store the number 551234. Well, when I do that, I’m going to start from left to right and I’m going to put in 5551-2234. And it fits just fine. No problems at all. This is how memory is supposed to work. This is not a buffer overflow. Now, what happens if I try to enter a number that’s too long. So for this example, let’s go ahead and put up two buffers.
We have buffer A and buffer B, and they’re adjacent to each other. Now, in the area I live in, we happen to have a lot of phone numbers and we have a lot of people. And so we couldn’t just use seven digits anymore. We have to use area codes. So even if you live in the same city, you might find people who have one of three different area codes. We have 301443 or four 10. So if I wanted to store your number, I would need to put in 410-55-1234. So that’s ten digits. Now, but my buffers were only set up for eight digits. So what’s going to happen when I try to store this number in buffer A? Well, I’m going to put in 410-5512 and then I run out of space, but I still have more numbers. And so I’m going to overflow the buffer and start filling up buffer B with the three four. This is a buffer overflow.
Now, this is a really simple example, but it gives you the idea of what’s happening. Now, if I can overflow the buffer, though, I can put whatever code I want into buffer B. Then when the program that was supposed to be using buffer B, it goes to read it. They’re now going to be reading what I put in there, in this case three four, which isn’t very helpful. But if I had the actual shellcode or some kind of an exploit, they can then read that exploit and run it. And that’s why a buffer overflow is so dangerous. So let’s get technical for just a second here. Now, when we start talking about this, a lot of times you hear the term stack. Now, a stack is a reserved area of memory where the program saves the return address when a function call instruction is received. So it looks something like this here I have my memory memory, and we’re going to fill from the bottom of the memory all the way to the top of the memory.
And you can see the buffer. Number two is there. We see a new code is there, we see a new pointer. Execution is there and the function call arguments are there. Now, what ends up happening when I tried to access my memory, if I buffer overflowed, in this case I overflowed buffer two and I put in new code, then what happens is I end up hitting that new code instead of the things I thought was sitting in that buffer. And so this is the whole idea of a buffer overflow and allows us to execute that malicious code, which in this case was shell code. Now, another thing you may hear people talk about is what’s known as smashing the stack or smash the stack. When you talk about smash the stack, this occurs when an attacker fills up the buffer with nops so that the return address may hit a knop and continue on until it finds the attacker’s code to run.
Now, what’s a knop? Well, NOP is a non operation. It means no operation. It’s basically blank space. So in assembly code, if you put in something called x 90, this is a knob. And so here in the memory, I would fill the buffer up with these knobs, this x 90. And as I do that over and over and over again, what ends up happening is any place in that knob that I hit when I do a return call to try to find the buffer where my actual data is, it’s going to hit that knob and it’s going to keep sliding down because there’s no no operation. No operation. No operation. And eventually it hits the end where that shellcode is and it will execute that shellcode, which is the exploit. This is how buffer overflow is going to work for us. So we want to prevent buffer overflows. Buffer overflows are really, really bad for us.
Now, before we talk about what you can do to prevent buffer overflows, we’re going to talk about the other two types of overflows, because all the techniques that we’re going to use to prevent buffer overflows also will work with these other two as well. So the second type we want to talk about is what’s known as a heap overflow. So a heap overflow is a software vulnerability where input is allowed to overwrite memory locations within the area of a processor’s. Memory allocation. That memory allocation is known as a heap. This is used to store dynamically sized variables. So with a heap overflow, we can override those variables and possibly allow arbitrary code execution, which, again, can be used to do all sorts of bad things like privilege escalation and other things like that.
So when we’re talking about a heap overflow, we’re talking about large segments of your memory. That’s what we’re trying to attack here. The last thing we want to talk about here is an integer overflow. Now, this is another type of overflow condition you can cause. Now, an integer overflow is an attack in which a computer result is too large to fit in its assigned storage space. This can cause the crashing or data corruption and it could trigger a buffer overflow. So, again, these things can lead to buffer overflows, which can then lead to arbitrary code execution, which can lead to privilege, escalation. And you can see how these things chain together to create a bad effect for us. So what is an integer? Well, an integer is essentially a whole number. So if you think about 12345, those are integers. If I count negatively negative one, negative two, negative three, negative four, negative five, those are integers as well.
But if I said 1. 5 or one half or three quarters, those are fractions, those are not integers. Anytime you have a decimal or a fraction, that is not considered an integer.Now, integers are a special type in computer programming and they only accept whole numbers. Now, these can be both positive or negative, but they can only go up to a certain size. For instance, you have what’s known as the upper bound and lower bound. Let’s say I had a two digit storage space. This is my two digit integers or storage space. I can store numbers either positive or negative up to two digits. So how big can my numbers be? Well, they can be zero all the way up to 99. And if I was allowing a negative number in here, it could be anywhere from zero down to negative 99. But that’s it. There’s a very limited amount of numbers. So let’s say I had some values.
I have 90 and 17 and I wanted to add those together. And then I want to store them here in my two digit system. Can I do it? Well, no, because 90 plus 17 is 107, which is three digits. So if I try to store it, I’m either going to get 10 or zero seven, depending on if my system stores from left to right or right to left when it fills memory. Either way, though, the system is going to lose one of those digits either at the front or the back due to the bounding because we have a high level bound here of 99. Now, if there was another space to the right of it, you could actually have an integer overflow because I would start filling from left to right and I would put 10 in the first bank and then I would put the seven in the second bank overflowing into that next integer. Now this is a really silly example because nobody’s going to use just a two digit system, but our computers actually have a limit to the size of integers they can use and so it can cause integer overflows.
And so this becomes big issue for us. We have to make sure that we think about this as we’re designing our software of how big is that value I’m trying to store? If I’m trying to store something like a dollar amount that we’re going to use for a purchase on my website, I’d probably be okay saying that the maximum value is going to be less than six digits because no one’s going to spend more than $999,999 at once. But if I’m doing something like putting in a Social Security number, that’s nine digits and that’s an integer. And so I have to be able to calculate how long these things need to be when I set up my integers. Now, why is this a big deal? Well, let’s say that these values on the screen represented the amount we were going to charge your credit card when you purchased a product.
If you could cause an overflow in this way, instead of being charged $107 you actually owed me, you might only be charged $10 or $7 or $70. And all three of these are bad for my business because we were expecting to collect $107 for you that you should have paid. And so oftentimes these integer overflows can be used as a precursor to a different type of attack or to modify the values that you want to process later on. Now, how can we protect our systems from all of these three types of exploits? Well, that’s the big question, isn’t it? Well, one of the most fundamental things you can do to help protect your system is picking the right programming language. Because there are hundreds of different programming languages out there. Some have been around for decades and some are relatively new. Some of the newer ones have a lot of these protections built in, some of the older ones don’t.
So if I’m using something like C Plus Plus or C, this uses a function like string copy and it doesn’t perform boundary checking of your buffers. And so you can have a buffer overflow occur. So a string copy, what it does is it’ll actually copy a value from one section of memory to another and it doesn’t check if it’s big enough to fit yet. And so you can very easily overflow that buffer. For example, string copy, which is used in C and C Plus Plus is a function that will copy a value from one string into memory into another location. Well, that’s great, but the problem is it doesn’t perform boundary checking of the buffers. So if I try to take something that is 16 digits long and put in a buffer that’s supposed to hold eight digits, I now can overrun the buffer. And that’s why C and C Plus Plus is very vulnerable to buffer overflow attacks.
Remember that for the exam. CNC plus is very vulnerable to buffer overflow attacks. It’s really important. That’s why I said it twice. Now, on the other hand, if you’re using a newer language like Java or Python or PHP, these can actually detect these overflow conditions and they can halt the program execution. This will prevent the overflow from occurring and so it does depend what language you’re going to choose. So with that said, let’s just all take all of our software and rewrite it all into Java because that’s going to be the most secure thing out there, right? Well, it’s not that easy. Changing our languages isn’t that easy because it requires a complete rebuild of your software. In most cases. If you have a lot of old software that was written in something like assembly or C or even C Plus Plus, which was really popular 20 years ago.
That hasn’t been updated to the benefits of modern languages like Java or Python or other things like that. And so if you want to convert everything over, that is a huge expense of taking all your legacy code and rebuilding everything from scratch. I like to think about it this way. I have a house, and on that house, it’s built on a foundation. That foundation is poured and it is cement on the floor. Right. And then we build the house on top of it. If there’s a problem with that foundation, you want to replace it. Can I just swap it out for a new one? Well, no, it’s really hard because everything is built on top of it. And so for me to do that, I have to pick up the house, move the house, take out the foundation, put a new foundation in, and then put the house back on. That’d be very time consuming, very expensive, and it would be very hard to do. And that’s the idea here.
When we start talking about changing all of our code from this old legacy code into this new modern operating systems, yes, it would be great if we could do that, but unfortunately, it’s too expensive. And so most of the time you’re not going to have that choice. So what can we do? We can make sure we do proper input validation. We can make sure we do proper boundary checking in our code. So if you’re going to use something like C or C plus plus, you’ve got to take the initiative to do those checks. Now, another precaution that’s been added recently is what’s known as ASLR, which is the address space, layout randomization. Now, as we talked about the heaps and the buffers in memory, it would be really great if I was an attacker and I knew exactly where things were going to be every single time.
Well, in the old days of Windows 95 and Windows 2000, that’s exactly how it was. You would actually know exactly where the Explorer exe program was every single time because it always went to the same spot. And so as an attacker, I could build exploits and know exactly where to point my pointers. So when we talk about address, space, layout randomization, the whole idea here is that we wanted to have a technique that randomizes where the components in a running application are placed in memory. This protects us from buffer overflows. So every time I load up Microsoft Word, it’s going to use a different place. Every time I load up Explorer, it’s going to go into a different place. And that allows us to prevent some of these buffer overflow attacks.
This is a standard feature in windows from windows seven windows, eight windows ten and beyond. This is pretty commonplace in all operating systems these days. And it’s a great thing to help us protect our running processes from buffer overflow attacks. Another thing we can do is we can make sure that when we’re allowing our program to run, we always run them with the least privilege. This will help prevent buffer overflow attacks as well, because if you’re running in the user space, you only have access to certain parts of the memory. If you’re running as a kernel or the operating system, you have access to the entire memory. And so, by running with least privilege, we can limit the damage of a buffer overflow attack.
Interesting posts
The Growing Demand for IT Certifications in the Fintech Industry
The fintech industry is experiencing an unprecedented boom, driven by the relentless pace of technological innovation and the increasing integration of financial services with digital platforms. As the lines between finance and technology blur, the need for highly skilled professionals who can navigate both worlds is greater than ever. One of the most effective ways… Read More »
CompTIA Security+ vs. CEH: Entry-Level Cybersecurity Certifications Compared
In today’s digital world, cybersecurity is no longer just a technical concern; it’s a critical business priority. With cyber threats evolving rapidly, organizations of all sizes are seeking skilled professionals to protect their digital assets. For those looking to break into the cybersecurity field, earning a certification is a great way to validate your skills… Read More »
The Evolving Role of ITIL: What’s New in ITIL 4 Managing Professional Transition Exam?
If you’ve been in the IT service management (ITSM) world for a while, you’ve probably heard of ITIL – the framework that’s been guiding IT professionals in delivering high-quality services for decades. The Information Technology Infrastructure Library (ITIL) has evolved significantly over the years, and its latest iteration, ITIL 4, marks a substantial shift in… Read More »
SASE and Zero Trust: How New Security Architectures are Shaping Cisco’s CyberOps Certification
As cybersecurity threats become increasingly sophisticated and pervasive, traditional security models are proving inadequate for today’s complex digital environments. To address these challenges, modern security frameworks such as SASE (Secure Access Service Edge) and Zero Trust are revolutionizing how organizations protect their networks and data. Recognizing the shift towards these advanced security architectures, Cisco has… Read More »
CompTIA’s CASP+ (CAS-004) Gets Tougher: What’s New in Advanced Security Practitioner Certification?
The cybersecurity landscape is constantly evolving, and with it, the certifications that validate the expertise of security professionals must adapt to address new challenges and technologies. CompTIA’s CASP+ (CompTIA Advanced Security Practitioner) certification has long been a hallmark of advanced knowledge in cybersecurity, distinguishing those who are capable of designing, implementing, and managing enterprise-level security… Read More »
Azure DevOps Engineer Expert Certification: What’s Changed in the New AZ-400 Exam Blueprint?
The cloud landscape is evolving at a breakneck pace, and with it, the certifications that validate an IT professional’s skills. One such certification is the Microsoft Certified: DevOps Engineer Expert, which is validated through the AZ-400 exam. This exam has undergone significant changes to reflect the latest trends, tools, and methodologies in the DevOps world.… Read More »