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