1
1

00:00:00,240  -->  00:00:01,980
<v Instructor>Reverse engineering.</v>
2

2

00:00:01,980  -->  00:00:03,540
In this lesson, we're going to talk
3

3

00:00:03,540  -->  00:00:05,610
about some different reverse engineering tools
4

4

00:00:05,610  -->  00:00:08,760
and techniques and why these are important to us.
5

5

00:00:08,760  -->  00:00:10,380
Now, as a cybersecurity analyst,
6

6

00:00:10,380  -->  00:00:12,600
you may be asked to do some reverse engineering,
7

7

00:00:12,600  -->  00:00:15,600
specifically of malware that was collected on your network.
8

8

00:00:15,600  -->  00:00:17,010
When you do reverse engineering,
9

9

00:00:17,010  -->  00:00:19,620
this is the process of analyzing the structure of hardware
10

10

00:00:19,620  -->  00:00:22,830
or software to reveal more about how it functions.
11

11

00:00:22,830  -->  00:00:23,663
Now, the challenge
12

12

00:00:23,663  -->  00:00:25,650
is that when you're doing reverse engineering,
13

13

00:00:25,650  -->  00:00:27,330
you have to start with a binary
14

14

00:00:27,330  -->  00:00:29,820
and that binary is an executable file.
15

15

00:00:29,820  -->  00:00:31,350
You can't just look at that binary
16

16

00:00:31,350  -->  00:00:32,790
and then figure out what it's doing.
17

17

00:00:32,790  -->  00:00:34,410
No, you need to actually take the time
18

18

00:00:34,410  -->  00:00:36,270
to decompose that executable
19

19

00:00:36,270  -->  00:00:38,370
into something that could be readable as code.
20

20

00:00:38,370  -->  00:00:40,230
Now, when you decompose the executable,
21

21

00:00:40,230  -->  00:00:42,660
you can do it into one of three things.
22

22

00:00:42,660  -->  00:00:45,450
You can do it into machine code, assembly code,
23

23

00:00:45,450  -->  00:00:47,190
or high-level code.
24

24

00:00:47,190  -->  00:00:48,840
Now, when we talk about machine code,
25

25

00:00:48,840  -->  00:00:50,520
this is software that has been assembled
26

26

00:00:50,520  -->  00:00:52,890
into binary instructions that are expressed
27

27

00:00:52,890  -->  00:00:56,220
as hexadecimal digits native to the processor platform.
28

28

00:00:56,220  -->  00:00:59,340
So if you're using an Intel-based processor,
29

29

00:00:59,340  -->  00:01:02,790
one of the modern ones, they're x86-64,
30

30

00:01:02,790  -->  00:01:05,100
that is the native processor that they use.
31

31

00:01:05,100  -->  00:01:06,990
And they have a certain instruction set.
32

32

00:01:06,990  -->  00:01:09,030
And so if you send this set of ones and zeros,
33

33

00:01:09,030  -->  00:01:10,140
it's going to do this function.
34

34

00:01:10,140  -->  00:01:12,030
If you set this other set of ones and zeros,
35

35

00:01:12,030  -->  00:01:13,290
it does something else.
36

36

00:01:13,290  -->  00:01:15,150
Those are the binary instructions.
37

37

00:01:15,150  -->  00:01:16,710
Now, to make it a little bit easier to read,
38

38

00:01:16,710  -->  00:01:18,540
we take eight bits at a time
39

39

00:01:18,540  -->  00:01:21,420
and we represent that by two hexadecimal digits.
40

40

00:01:21,420  -->  00:01:23,970
This way, we can use that bite code
41

41

00:01:23,970  -->  00:01:26,970
to be able to read what was being told to the processor.
42

42

00:01:26,970  -->  00:01:31,470
For example, if I have this, 48, 89, 32,
43

43

00:01:31,470  -->  00:01:33,060
that is a three byte instruction
44

44

00:01:33,060  -->  00:01:35,220
that is written in machine code.
45

45

00:01:35,220  -->  00:01:37,440
Now, can you understand what this thing is doing?
46

46

00:01:37,440  -->  00:01:38,273
No?
47

47

00:01:38,273  -->  00:01:39,660
Well, neither can I just by looking at,
48

48

00:01:39,660  -->  00:01:41,250
but I actually looked it up.
49

49

00:01:41,250  -->  00:01:42,270
And if we actually look at this
50

50

00:01:42,270  -->  00:01:44,760
and try to reverse engineer the machine level code
51

51

00:01:44,760  -->  00:01:47,460
into something that we can read like this binary,
52

52

00:01:47,460  -->  00:01:49,530
it can take a lot of time for us to be able to go through it
53

53

00:01:49,530  -->  00:01:52,530
because now, we have this series of hexadecimal numbers
54

54

00:01:52,530  -->  00:01:53,640
and we'd have to look them up
55

55

00:01:53,640  -->  00:01:55,650
and figure out exactly what they mean.
56

56

00:01:55,650  -->  00:01:59,760
Now, in this case, 48, 89, 32 is telling the system
57

57

00:01:59,760  -->  00:02:02,190
to store the value received into a variable
58

58

00:02:02,190  -->  00:02:04,560
that's stored at a particular location of memory.
59

59

00:02:04,560  -->  00:02:07,020
Again, not very helpful yet, right?
60

60

00:02:07,020  -->  00:02:09,420
Let's go ahead and take this up one more level.
61

61

00:02:09,420  -->  00:02:11,601
We can use something called a disassembler.
62

62

00:02:11,601  -->  00:02:14,160
Now, a disassembler can take that machine language
63

63

00:02:14,160  -->  00:02:16,770
and they can reverse engineer it to be able to convert it
64

64

00:02:16,770  -->  00:02:19,950
from machine language code into assembly language code.
65

65

00:02:19,950  -->  00:02:21,960
Now, once we get it into assembly code,
66

66

00:02:21,960  -->  00:02:25,110
we have assembly code that is a compiled software program
67

67

00:02:25,110  -->  00:02:27,240
that's converted to binary machine code
68

68

00:02:27,240  -->  00:02:30,150
using the instruction set of that CPU platform.
69

69

00:02:30,150  -->  00:02:33,600
And now, it's actually represented in human readable text.
70

70

00:02:33,600  -->  00:02:36,090
So instead of using just the hexadecimal characters,
71

71

00:02:36,090  -->  00:02:38,310
I can use things that are written more in ASCII,
72

72

00:02:38,310  -->  00:02:40,380
something that I can actually read.
73

73

00:02:40,380  -->  00:02:41,213
So if I want to look
74

74

00:02:41,213  -->  00:02:43,290
at some typical instructions for assembly,
75

75

00:02:43,290  -->  00:02:46,020
you might see things like instructions for moving things
76

76

00:02:46,020  -->  00:02:48,150
between one register and memory to another.
77

77

00:02:48,150  -->  00:02:51,060
That's things like int or push or move.
78

78

00:02:51,060  -->  00:02:53,580
We might perform logical bitwise operations,
79

79

00:02:53,580  -->  00:02:56,790
like not, and, or, or xor.
80

80

00:02:56,790  -->  00:02:58,620
We might perform mathematical operations,
81

81

00:02:58,620  -->  00:03:02,370
like adding, subtracting, incrementing or decrementing.
82

82

00:03:02,370  -->  00:03:05,100
Or we could perform branching, things like a jump.
83

83

00:03:05,100  -->  00:03:08,490
Or we can use test conditions like compare or test.
84

84

00:03:08,490  -->  00:03:11,730
All of these are things that we can use inside of assembly.
85

85

00:03:11,730  -->  00:03:13,590
And so basically, there are these two or three
86

86

00:03:13,590  -->  00:03:16,830
or four letter codes that tell an instruction of what to do.
87

87

00:03:16,830  -->  00:03:19,020
Now again, these aren't really easy to read
88

88

00:03:19,020  -->  00:03:20,040
but they're a lot easier
89

89

00:03:20,040  -->  00:03:22,350
than looking at binary or hexadecimal.
90

90

00:03:22,350  -->  00:03:24,690
For instance, if I have something like this,
91

91

00:03:24,690  -->  00:03:28,320
movq %rsi, (%rdx), what is this saying?
92

92

00:03:32,040  -->  00:03:34,380
Well, this is an example of that three byte instruction
93

93

00:03:34,380  -->  00:03:36,420
that I had earlier from machine code.
94

94

00:03:36,420  -->  00:03:39,930
So instead of saying 48, 89, 32,
95

95

00:03:39,930  -->  00:03:41,670
I can now have it written this way.
96

96

00:03:41,670  -->  00:03:43,410
Now, this still isn't really easy to read
97

97

00:03:43,410  -->  00:03:46,110
but it's certainly better than that machine code was.
98

98

00:03:46,110  -->  00:03:48,330
So even if you don't know assembly language,
99

99

00:03:48,330  -->  00:03:49,320
you could probably see this
100

100

00:03:49,320  -->  00:03:51,750
and figure out it's doing something with moving
101

101

00:03:51,750  -->  00:03:55,140
because we have movq there, and this is going to move data
102

102

00:03:55,140  -->  00:03:56,910
from one place to another in memory.
103

103

00:03:56,910  -->  00:03:59,280
Now, the reason it says movq instead of move
104

104

00:03:59,280  -->  00:04:02,130
is because this is written for a 64-bit processor
105

105

00:04:02,130  -->  00:04:05,100
and it supports the movement of quads of memory.
106

106

00:04:05,100  -->  00:04:09,150
And so this is a movq or four bytes at a time.
107

107

00:04:09,150  -->  00:04:11,610
Now, the next thing we want to talk about is a decompiler.
108

108

00:04:11,610  -->  00:04:14,190
So we took something from machine code
109

109

00:04:14,190  -->  00:04:18,360
and we brought it up to assembly by using the disassembler.
110

110

00:04:18,360  -->  00:04:21,210
Now, if we take that assembly and we want to go higher,
111

111

00:04:21,210  -->  00:04:22,650
we would use a decompiler.
112

112

00:04:22,650  -->  00:04:25,410
A decompiler is a reverse engineering tool
113

113

00:04:25,410  -->  00:04:28,320
that converts that machine code or assembly language code
114

114

00:04:28,320  -->  00:04:32,340
to code in a specific higher level language or pseudocode.
115

115

00:04:32,340  -->  00:04:34,260
Now, when we talk about higher level code
116

116

00:04:34,260  -->  00:04:36,750
we're talking about code that is easier to read for humans.
117

117

00:04:36,750  -->  00:04:37,890
They can read it, write it
118

118

00:04:37,890  -->  00:04:40,140
and understand it much more natively.
119

119

00:04:40,140  -->  00:04:42,330
For example, if I had some code like this,
120

120

00:04:42,330  -->  00:04:45,660
which is written in C, C is considered a high-level language
121

121

00:04:45,660  -->  00:04:47,460
with code that's fairly easy to read
122

122

00:04:47,460  -->  00:04:49,650
for somebody with some basic training.
123

123

00:04:49,650  -->  00:04:51,510
Even if you haven't known C in the past,
124

124

00:04:51,510  -->  00:04:52,560
you can probably look at this
125

125

00:04:52,560  -->  00:04:54,210
and figure out what it's doing.
126

126

00:04:54,210  -->  00:04:55,620
What do you think it's doing?
127

127

00:04:55,620  -->  00:04:59,070
It's assigning the value of T into the variable dest,
128

128

00:04:59,070  -->  00:04:59,903
or in this case,
129

129

00:04:59,903  -->  00:05:02,340
the destination location of a piece of memory.
130

130

00:05:02,340  -->  00:05:03,173
And that's all we're doing.
131

131

00:05:03,173  -->  00:05:05,520
It's the same code that we were using before.
132

132

00:05:05,520  -->  00:05:06,870
I can write it this way
133

133

00:05:06,870  -->  00:05:08,580
or I can write it with the move statement,
134

134

00:05:08,580  -->  00:05:11,820
or I can write it as 48, 89, 32.
135

135

00:05:11,820  -->  00:05:14,220
All three do the exact same thing,
136

136

00:05:14,220  -->  00:05:17,400
but this one is by far the easiest to understand.
137

137

00:05:17,400  -->  00:05:20,040
Now, another way you can do this is by using pseudocode.
138

138

00:05:20,040  -->  00:05:22,020
Pseudocode is not real code.
139

139

00:05:22,020  -->  00:05:24,300
The code I just showed you was actually C,
140

140

00:05:24,300  -->  00:05:26,580
but pseudocode can just be a made up language
141

141

00:05:26,580  -->  00:05:28,650
that your decompiler is going to use.
142

142

00:05:28,650  -->  00:05:31,590
Pseudocode makes it easier to identify individual functions
143

143

00:05:31,590  -->  00:05:34,110
within the process, track the use of variables,
144

144

00:05:34,110  -->  00:05:36,390
and to find branching logic.
145

145

00:05:36,390  -->  00:05:37,770
Now, when you're dealing with this,
146

146

00:05:37,770  -->  00:05:39,810
you want to use a tool to do this.
147

147

00:05:39,810  -->  00:05:41,730
Now, what is the most common tool out there
148

148

00:05:41,730  -->  00:05:44,280
when it comes to decompiling and disassembly?
149

149

00:05:44,280  -->  00:05:45,750
Well, IDA.
150

150

00:05:45,750  -->  00:05:50,310
IDA is a interactive disassembler, also known as IDA, IDA.
151

151

00:05:50,310  -->  00:05:53,490
This is a popular cross-platform disassembler and decompiler
152

152

00:05:53,490  -->  00:05:55,440
that's often used by reverse engineers.
153

153

00:05:55,440  -->  00:05:56,670
If you happen to take a course
154

154

00:05:56,670  -->  00:05:58,320
in reverse malware engineering,
155

155

00:05:58,320  -->  00:06:01,230
you're going to get really familiar with how to use IDA.
156

156

00:06:01,230  -->  00:06:03,630
Now, IDA has an automated functionality as well
157

157

00:06:03,630  -->  00:06:06,030
that's able to identify different API calls,
158

158

00:06:06,030  -->  00:06:07,860
function parameters constraints
159

159

00:06:07,860  -->  00:06:10,620
and other components of the disassembled code.
160

160

00:06:10,620  -->  00:06:13,830
In this particular example, IDA has taken the machine code
161

161

00:06:13,830  -->  00:06:17,340
from the binary, disassembled back into assembly language,
162

162

00:06:17,340  -->  00:06:19,050
and then use this decompiler function
163

163

00:06:19,050  -->  00:06:20,460
to make it more human readable
164

164

00:06:20,460  -->  00:06:22,440
by giving us this high level pseudocode
165

165

00:06:22,440  -->  00:06:25,500
that looks something like a C or a C++ program.
166

166

00:06:25,500  -->  00:06:26,670
You can see that on the right,
167

167

00:06:26,670  -->  00:06:28,590
all the pseudocode on the right side,
168

168

00:06:28,590  -->  00:06:30,750
and this would help us decompile this malware
169

169

00:06:30,750  -->  00:06:32,310
and figure out what it's doing.
170

170

00:06:32,310  -->  00:06:33,270
Now, programmers,
171

171

00:06:33,270  -->  00:06:35,970
if they want to make their code more difficult to analyze,
172

172

00:06:35,970  -->  00:06:38,370
they can do this by using an obfuscator.
173

173

00:06:38,370  -->  00:06:40,200
An obfuscator is basically a software
174

174

00:06:40,200  -->  00:06:42,900
that's going to randomize the names of variables, constants,
175

175

00:06:42,900  -->  00:06:45,420
functions, procedures and removes comments,
176

176

00:06:45,420  -->  00:06:47,850
and all the white space inside a code.
177

177

00:06:47,850  -->  00:06:50,370
This makes it harder for us as malware analysts
178

178

00:06:50,370  -->  00:06:51,660
to be able to go through that code
179

179

00:06:51,660  -->  00:06:53,700
and figure out what the malware writer is doing,
180

180

00:06:53,700  -->  00:06:54,810
which is their goal
181

181

00:06:54,810  -->  00:06:56,760
because they want to keep the secret sauce
182

182

00:06:56,760  -->  00:06:59,730
of their malware secret so that we can't write signatures
183

183

00:06:59,730  -->  00:07:00,990
to block in the future.
184

184

00:07:00,990  -->  00:07:03,120
And if we can go through and reverse engineer their code,
185

185

00:07:03,120  -->  00:07:04,530
we can understand what it's doing,
186

186

00:07:04,530  -->  00:07:06,870
we can block IP addresses, block domain names,
187

187

00:07:06,870  -->  00:07:08,670
or whatever else they're using for beaconing,
188

188

00:07:08,670  -->  00:07:10,710
callouts and other exfiltration.
189

189

00:07:10,710  -->  00:07:14,010
Now, debugging tools are used to decompile executables
190

190

00:07:14,010  -->  00:07:16,080
and observe their behavior.
191

191

00:07:16,080  -->  00:07:17,880
When we're talking about debugging tools,
192

192

00:07:17,880  -->  00:07:21,060
this is things like Immunity Debugger, GDB,
193

193

00:07:21,060  -->  00:07:22,590
and SearchSploit.
194

194

00:07:22,590  -->  00:07:25,230
First, we have the Immunity Debugger.
195

195

00:07:25,230  -->  00:07:27,960
Immunity Debugger is a debugger built specifically
196

196

00:07:27,960  -->  00:07:31,800
for penetration testers to write exploits, analyze malware,
197

197

00:07:31,800  -->  00:07:33,660
and reverse engineer binary files
198

198

00:07:33,660  -->  00:07:36,630
using python scripts and APIs.
199

199

00:07:36,630  -->  00:07:38,940
The main difference between the Immunity Debugger
200

200

00:07:38,940  -->  00:07:41,820
and OllyDBG is that the Immunity Debugger
201

201

00:07:41,820  -->  00:07:44,490
also supports a Python API plugin
202

202

00:07:44,490  -->  00:07:46,440
that allows us to execute Python code
203

203

00:07:46,440  -->  00:07:47,970
from within this debugger,
204

204

00:07:47,970  -->  00:07:51,300
and that allows penetration testers to work quicker.
205

205

00:07:51,300  -->  00:07:52,560
If you're a penetration tester
206

206

00:07:52,560  -->  00:07:54,210
who does a lot of custom coding,
207

207

00:07:54,210  -->  00:07:57,270
you're really going to love using the Immunity Debugger.
208

208

00:07:57,270  -->  00:08:01,440
Second, we have GDB or the GNU Debugger.
209

209

00:08:01,440  -->  00:08:04,410
This is an open source cross-platform debugger
210

210

00:08:04,410  -->  00:08:07,830
for Unix, Windows, and Mac OS.
211

211

00:08:07,830  -->  00:08:12,830
Now, GDB or the GNU Debugger supports Ada, C, C++,
212

212

00:08:13,410  -->  00:08:17,670
Objective-C, Pascal, Fortran, Go, Java,
213

213

00:08:17,670  -->  00:08:20,130
and many other programming languages.
214

214

00:08:20,130  -->  00:08:22,590
However, because it is a text-based program
215

215

00:08:22,590  -->  00:08:24,690
that works inside the Linux console,
216

216

00:08:24,690  -->  00:08:26,880
it's not incredibly user-friendly
217

217

00:08:26,880  -->  00:08:29,580
even though it supports so many languages,
218

218

00:08:29,580  -->  00:08:31,860
and therefore, most penetration testers
219

219

00:08:31,860  -->  00:08:33,480
prefer to use other debuggers
220

220

00:08:33,480  -->  00:08:36,330
like the Immunity Debugger instead.
221

221

00:08:36,330  -->  00:08:38,670
Our final tool we're going to talk about in debuggers,
222

222

00:08:38,670  -->  00:08:40,890
it's SearchSploit, and this is another one
223

223

00:08:40,890  -->  00:08:44,250
where it doesn't quite cleanly fit into the category.
224

224

00:08:44,250  -->  00:08:46,530
SearchSploit is a tool used to find exploits
225

225

00:08:46,530  -->  00:08:49,080
that are available in the exploit database.
226

226

00:08:49,080  -->  00:08:51,900
So you may be wondering if this is a research tool,
227

227

00:08:51,900  -->  00:08:54,120
why is it showing up under debuggers?
228

228

00:08:54,120  -->  00:08:56,610
Well, we're covering SearchSploit in this lesson
229

229

00:08:56,610  -->  00:08:58,530
because we often use SearchSploit
230

230

00:08:58,530  -->  00:09:01,320
while we're reading different malware in a debugger,
231

231

00:09:01,320  -->  00:09:03,240
so that we can understand what a particular piece
232

232

00:09:03,240  -->  00:09:05,370
of exploit code might actually be doing
233

233

00:09:05,370  -->  00:09:07,320
for that particular piece of malware.
234

234

00:09:07,320  -->  00:09:09,540
So I could see it from that perspective
235

235

00:09:09,540  -->  00:09:12,270
where we use this hand in hand with debuggers,
236

236

00:09:12,270  -->  00:09:14,940
but it itself is not a debugger tool.
237

237

00:09:14,940  -->  00:09:18,270
Instead, it is a tool that's used to research exploit code
238

238

00:09:18,270  -->  00:09:19,920
in the central database.
239

239

00:09:19,920  -->  00:09:22,440
By having SearchSploit installed on your system though,
240

240

00:09:22,440  -->  00:09:25,080
you can download a copy of that database locally
241

241

00:09:25,080  -->  00:09:27,690
so you can work offline when you're doing your debugging
242

242

00:09:27,690  -->  00:09:30,340
and be able to have access to that research database.
