Instructor: Overflow attacks. 2 2
In this lesson, we're going to talk 3 3
about the three types of overflow attacks. 4 4
This includes buffer overflows, heap overflows 5 5
and integer overflows. 6 6
And as we go through, 7 7
I'm going to explain a little bit about each one. 8 8
Now, when I talk about a buffer overflow, 9 9
this is an attack in which data goes to the boundary 10 10
of the destination buffer, and then it begins 11 11
to corrupt the adjacent memory 12 12
and essentially, it overflows. 13 13
So if we're talking about a buffer, what exactly is that? 14 14
Well, essentially, any temporary storage area 15 15
that a program is going to use to store data. 16 16
This might be a variable or user-created data. 17 17
Now, the way I like to think about a buffer 18 18
in a visual format is to think about a glass of water. 19 19
Let's say I have a glass 20 20
and I put it on the table and it's a 16-ounce glass. 21 21
Well, that means how many ounces can it hold? 22 22
16 ounces. 23 23
If I try putting 15 ounces, will it hold it? Yeah. 24 24
If I try to put in five ounces, will it hold it? Yeah. 25 25
If I try to put in 20 ounces, what's going to happen? 26 26
It's going to overflow 27 27
and it's going to get a mess all over my table. 28 28
Well, the same thing happens in memory. 29 29
Your memory is set up 30 30
to hold a certain amount of information. 31 31
And when a program starts up, it allocates a certain amount 32 32
of memory for its ability to store stuff. 33 33
And so if it says, I'm going to store 16 ounces 34 34
and then you try to shove 20 ounces in there, 35 35
it's going to overflow into the adjacent memory cells. 36 36
So think of I had three or four glasses sitting next to it 37 37
and the water would start filling those glasses. 38 38
That's the idea of a buffer overflow. 39 39
Now, why are these so dangerous? 40 40
Well, as we look back 41 41
to the different data breaches that occurred, 42 42
over 85% of data breaches were caused initially 43 43
by a buffer overflow attack. 44 44
And so this is a really dangerous area for us. 45 45
Let me go ahead and give you another example of this 46 46
that I use in my Security+ courses. 47 47
Let's say I want to store your phone number. 48 48
I pull out my cell phone and I want to type it in. 49 49
Well, how does a phone number look? 50 50
If you use an old phone number, 51 51
it might look here in the United States like seven digits. 52 52
So I might have something like 555-1234. 53 53
Now, let's say I set up my buffer as an eight-bit buffer 54 54
because I was expecting seven digits. 55 55
So I have an eight-bit buffer 56 56
and I'm going to store the number 555-1234. 57 57
Well, when I do that, I'm going to start 58 58
from left to right and I'm going to put in 555-1234, 59 59
and it fits just fine. 60 60
No problems at all. 61 61
This is how memory is supposed to work. 62 62
This is not a buffer overflow. 63 63
Now, what happens if I try to enter a number 64 64
that's too long? 65 65
So for this example, let's go ahead and put up two buffers. 66 66
We have buffer A and buffer B, 67 67
and they're adjacent to each other. 68 68
Now, in the area I live in, we happen to have a lot 69 69
of phone numbers and we have a lot of people. 70 70
And so we couldn't just use seven digits anymore. 71 71
We have to use area codes. 72 72
So even if you live in the same city, you might find people 73 73
who have one of three different area codes. 74 74
We have 301, 443 or 410. 75 75
So if I wanted to store your number, 76 76
I would need to put in 410-555-1234. 77 77
So that's 10 digits now, but my buffers were only set up 78 78
for eight digits. 79 79
So what's going to happen when I try 80 80
to store this number in buffer a? 81 81
Well, I'm going to put in 410-555-12 82 82
and then I run out of space, but I still have more numbers. 83 83
And so I'm going to overflow the buffer 84 84
and start filling up buffer B with the 34. 85 85
This is a buffer overflow. 86 86
Now, this is a really simple example 87 87
but it gives you the idea of what's happening. 88 88
Now, if I can overflow the buffer though, 89 89
I can put whatever code I want into buffer B. 90 90
Then when the program that was supposed 91 91
to be using buffer B, it goes to read it, 92 92
they're now going to be reading what I put in there, 93 93
in this case, 34, which isn't very helpful. 94 94
But if I had the actual shell code or some kind 95 95
of an exploit, they can then read that exploit and run it. 96 96
And that's why a buffer overflow's so dangerous. 97 97
So let's get technical for just a second here. 98 98
Now, when we start talking about this, 99 99
a lot of times you hear the term stack. 100 100
Now, a stack is a reserved area of memory 101 101
where the program saves the return address 102 102
when a function call instruction is received. 103 103
So it looks something like this. 104 104
Here I have my memory, and we're going to fill 105 105
from the bottom of the memory all the way 106 106
to the top of the memory, and you can see 107 107
that buffer number two is there, we see new code is there. 108 108
We see a new pointer execution is there 109 109
and the function call arguments are there. 110 110
Now, what ends up happening when I try to access my memory 111 111
if I buffer overflowed, 112 112
in this case, I overflowed buffer two and I put in new code, 113 113
then what happens is I end up hitting that new code instead 114 114
of the things I thought was sitting in that buffer. 115 115
And so this is the whole idea of a buffer overflow 116 116
and allows us to execute that malicious code, 117 117
which in this case, was shell code. 118 118
Now, another thing you may hear people talk about 119 119
is what's known as smashing the stack or smash the stack. 120 120
When you talk about smash the stack, 121 121
this occurs when an attacker fills up the buffer 122 122
with NOPs so that the return address may hit a NOP 123 123
and continue on until it finds the attacker's code to run. 124 124
Now, what's a NOP? 125 125
Well, is a non-operation, means no operation. 126 126
It's basically a blank space. 127 127
So in assembly code, if you put in something called x90, 128 128
this is a NOP. 129 129
And so here in the memory, 130 130
I would fill the buffer up with these NOPs, this x90. 131 131
And as I do that, over and over and over again, 132 132
what ends up happening is any place in that NOP 133 133
that I hit when I do a return call to try 134 134
to find the buffer where my actual data is, 135 135
it's going to hit that NOP and it's going to keep sliding down 136 136
because there's no operation, no operation, no operation. 137 137
And eventually, it hits the end where that shell code is, 138 138
and it will execute that shell code, which is the exploit. 139 139
This is how a buffer overflow is going to work for us. 140 140
So we want to prevent buffer overflows. 141 141
Buffer overflows are really, really bad for us. 142 142
Now, before we talk about what you can do 143 143
to prevent buffer overflows, 144 144
we're going to talk about the other two types of overflows 145 145
because all the techniques that we're going to use 146 146
to prevent buffer overflows also will work 147 147
with these other two as well. 148 148
So the second type we want to talk about 149 149
is what's known as a heap overflow. 150 150
So a heap overflow is a software vulnerability 151 151
where input is allowed to overwrite memory locations 152 152
within the area of a processor's memory allocation. 153 153
That memory allocation is known as a heap. 154 154
This is used to store dynamically sized variables. 155 155
So with a heap overflow, we can overwrite those variables 156 156
and possibly allow arbitrary code execution, which again, 157 157
can be used to do all sorts of bad things, 158 158
like privilege escalation and other things like that. 159 159
So when we're talking about a heap overflow, 160 160
we're talking about large segments of your memory. 161 161
That's what we're trying to attack here. 162 162
The last thing we want to talk about here 163 163
is the integer overflow. 164 164
Now, this is another type 165 165
of overflow condition you can cause. 166 166
Now, an integer overflow is an attack 167 167
in which a computer result is too large to fit 168 168
in its assigned storage space. 169 169
This can cause crashing or data corruption 170 170
and it could trigger a buffer overflow. 171 171
So again, these things can lead to buffer overflows, 172 172
which can then lead to arbitrary code execution, 173 173
which can lead to privileged escalation. 174 174
And you can see how these things chain together 175 175
to create a bad effect for us. 176 176
So what is an integer? 177 177
Well, an integer is essentially a whole number. 178 178
So if you think about one, two, three, four, five, 179 179
those are integers. 180 180
And if I count negatively, negative one, 181 181
negative two, negative three, negative four, negative five, 182 182
those are integers as well. 183 183
But if I said 1.5 or 1/2 or 3/4, 184 184
those are fractions, those are not integers. 185 185
Anytime you have a decimal or a fraction, 186 186
that is not considered an integer. 187 187
Now, integers are a special type 188 188
in computer programming and they only accept whole numbers. 189 189
Now, these can be both positive or negative 190 190
but they can only go up to a certain size. 191 191
For instance, you have what's known 192 192
as the upper bound and lower bound. 193 193
Let's say I had a two-digit storage space. 194 194
This is my two-digit integer storage space. 195 195
I can store numbers, either positive or negative, 196 196
up to two digits. 197 197
So how big can my numbers be? 198 198
Well, they can be zero all the way up to 99. 199 199
And if I was allowing a negative number in here, 200 200
it could be anywhere from zero down to negative 99, 201 201
but that's it. 202 202
There's a very limited amount of numbers. 203 203
So let's say I had some values, 204 204
I have 90 and 17 and I wanted to add those together 205 205
and then I want to store them here in my two-digit system. 206 206
Can I do it? 207 207
Well, no, because 90 plus 17 is 107, which is three digits. 208 208
So if I try to store it, I'm either going to get 10 or 07, 209 209
depending on if my system stores from left to right 210 210
or right to left when it fills memory. 211 211
Either way though, the system is going to lose one 212 212
of those digits either at the front 213 213
or the back due to the bounding 214 214
because we have a high level bound here of 99. 215 215
Now, if there was another space to the right of it, 216 216
you could actually have an integer overflow 217 217
because I would start filling from left to right, 218 218
and I would put one zero 219 219
in the first bank and then I would put the seven 220 220
in the second bank overflowing into that next integer. 221 221
Now, this is a really silly example 222 222
because nobody's going to use just a two-digit system 223 223
but our computers actually have a limit 224 224
to the size of integers they can use. 225 225
And so it can cause integer overflows. 226 226
And so this becomes a big issue for us. 227 227
We have to make sure that we think about this 228 228
as we're designing our software 229 229
of how big is that value I'm trying to store? 230 230
If I'm trying to store something 231 231
like a dollar amount that we're going to use 232 232
for a purchase on my website, I'd probably be okay saying 233 233
that the maximum value is going to be less than six digits 234 234
'cause no one's going to spend more than $999,999 at once. 235 235
But if I'm doing something 236 236
like putting in a Social Security number, 237 237
that's nine digits and that's an integer. 238 238
And so I have to be able to calculate 239 239
how long these things need to be when I set up my integers. 240 240
Now, why is this a big deal? 241 241
Well, let's say that these values 242 242
on the screen represented the amount 243 243
we were going to charge your credit card 244 244
when you you purchased a product. 245 245
If you could cause an overflow in this way, 246 246
instead of being charged $107 you actually owed me, 247 247
you might only be charged $10 or $7 or $70. 248 248
And all three of these are bad for my business 249 249
because we were expecting to collect $107 for you 250 250
that you should have paid. 251 251
And so oftentimes, these integer overflows can be used 252 252
as a precursor to a different type of attack 253 253
or to modify the values that you want to process later on. 254 254
Now, how can we protect our systems 255 255
from all of these three types of exploits? 256 256
Well, that's the big question, isn't it? 257 257
Well, one of the most fundamental things you can do 258 258
to help protect your system is picking 259 259
the right programming language because there are hundreds 260 260
of different programming languages out there. 261 261
Some have been around for decades 262 262
and some are relatively new. 263 263
Some of the newer ones have a lot 264 264
of these protections built in, some of the older ones don't. 265 265
So if I'm using something like C++, or C, 266 266
this uses a function like string copy 267 267
and it doesn't perform boundary checking of your buffers. 268 268
And so you can have a buffer overflow occur. 269 269
For example, string copy, which is used in C and C++ 270 270
is a function that will copy a value 271 271
from one string into memory into another location. 272 272
Well, that's great but the problem 273 273
is it doesn't perform boundary checking 274 274
of the buffers. 275 275
So if I try to take something that is 16 digits long 276 276
and put in a buffer that's supposed to hold eight digits, 277 277
I now can overrun the buffer. 278 278
And that's why C and C++ is very vulnerable 279 279
to buffer overflow attacks. 280 280
Remember that for the exam. 281 281
C and C++ is very vulnerable to buffer overflow attacks. 282 282
It's really important. 283 283
That's why I said it twice. 284 284
Now, on the other hand, if you're using a newer language 285 285
like Java or Python or PHP, 286 286
these can actually detect these overflow conditions 287 287
and they can halt the program execution. 288 288
This will prevent the overflow from occurring. 289 289
And so it does depend what language you're going to choose. 290 290
So with that said, let's just all take all 291 291
of our software and rewrite it all into Java 292 292
because that's going to be 293 293
the most secure thing out there, right? 294 294
Well, it's not that easy. 295 295
Changing our languages isn't that easy 296 296
because it requires a complete rebuild of your software 297 297
in most cases. 298 298
If you have a lot of old software 299 299
that was written in something 300 300
like Assembly or C or even C++, 301 301
which was really popular 20 years ago, 302 302
that hasn't been updated to the benefits of modern languages 303 303
like Java or Python or other things like that. 304 304
And so if you want to convert everything over, 305 305
that is a huge expense of taking all your legacy code 306 306
and rebuilding everything from scratch. 307 307
I like to think about it this way. 308 308
I have a house and on that house, 309 309
it's built on a foundation. 310 310
That foundation is poured and it has cement on the floor. 311 311
And then we build the house on top of it. 312 312
If there's a problem with that foundation, 313 313
you want to replace it, 314 314
can I just swap it out for a new one? 315 315
Well, no, it's really hard 316 316
because everything is built on top of it. 317 317
And so for me to do that, I'd have to pick up the house, 318 318
move the house, take out the foundation, 319 319
put a new foundation in, and then put the house back on. 320 320
That'd be very time consuming, very expensive 321 321
and it'd be very hard to do. 322 322
And that's the idea here when we start talking 323 323
about changing all of our code from this old legacy code 324 324
into this new modern operating systems. 325 325
Yes, it would be great if we could do that, 326 326
but unfortunately, it's too expensive. 327 327
And so most of the time, you're not going to have that choice. 328 328
So what can we do? 329 329
We can make sure we do proper input validation, 330 330
we can make sure we do proper boundary checking in our code. 331 331
So if you're going to use something like C or C++, 332 332
you've got to take the initiative to do those checks. 333 333
Now, another precaution that's been added recently 334 334
is what's known as ASLR, 335 335
which is the Address Space Layout Randomization. 336 336
Now, as we talked about the heaps and the buffers in memory, 337 337
it would be really great if I was an attacker 338 338
and I knew exactly where things were going to be 339 339
every single time. 340 340
Well, in the old days of Windows 95 and Windows 2000, 341 341
that's exactly how it was. 342 342
You would actually know exactly 343 343
where the explorer.exe program was every single time 344 344
because it always went to the same spot. 345 345
And so as an attacker, I could build exploits 346 346
and know exactly where to point my pointers. 347 347
So when we talk about Address Space Layout Randomization, 348 348
the whole idea here is that we wanted to have a technique 349 349
that randomizes where the components 350 350
in a running application are placed in memory. 351 351
This protects us from buffer overflows. 352 352
So every time I load up Microsoft Word, 353 353
it's going to use a different place. 354 354
Every time I load up Explorer, it's going to go 355 355
into a different place, and that allows us to prevent some 356 356
of these buffer overflow attacks. 357 357
This is a standard feature in Windows 358 358
from Windows 7, Windows 8, Windows 10 and beyond. 359 359
This is pretty commonplace 360 360
in all operating systems these days 361 361
and it's a great thing to help us protect 362 362
our running processes from buffer overflow attacks. 363 363
Another thing we can do is we can make sure 364 364
that when we're allowing our programs to run, 365 365
we always run them with the least privilege. 366 366
This will help prevent buffer overflow attacks as well 367 367
because if you're running in the user space, 368 368
you only have access to certain parts of the memory. 369 369
If you're running as a kernel or the operating system, 370 370
you have access to the entire memory. 371 371
And so by running with least privilege, 372 372
we can limit the damage of a buffer overflow attack.