WEBVTT

1
00:00:00.120 --> 00:00:04.679
<v Speaker 1>Imagine you've just intercepted this highly suspicious iOS application file.

2
00:00:05.759 --> 00:00:08.759
<v Speaker 1>It's just sitting right there in your sandbox, effectively, you know,

3
00:00:09.000 --> 00:00:12.320
<v Speaker 1>a locked black box right just waiting to be opened exactly,

4
00:00:12.839 --> 00:00:15.880
<v Speaker 1>and you need to know its exact capabilities, like what's

5
00:00:15.919 --> 00:00:19.039
<v Speaker 1>its network infrastructure? What is the ultimate payload here?

6
00:00:19.120 --> 00:00:20.399
<v Speaker 2>Which you can't just double click it?

7
00:00:20.559 --> 00:00:24.280
<v Speaker 1>No, absolutely not running it. Actually executing that file on

8
00:00:24.320 --> 00:00:28.719
<v Speaker 1>a test device could unleash absolute chaos, I mean, potentially

9
00:00:28.760 --> 00:00:33.000
<v Speaker 1>burning your entire analysis environment, or even worse, alerting the

10
00:00:33.039 --> 00:00:36.159
<v Speaker 1>malware's command and control servers that you're actively watching them.

11
00:00:36.240 --> 00:00:39.479
<v Speaker 2>Yeah, it's basically the ultimate digital bomb disposal scenario. It

12
00:00:39.560 --> 00:00:45.280
<v Speaker 2>really is your task with mapping the internal wiring, analyzing

13
00:00:45.320 --> 00:00:48.759
<v Speaker 2>the chemical composition of the explosive, and you know, tracing

14
00:00:48.759 --> 00:00:50.799
<v Speaker 2>the detonator. But you have to do all of that

15
00:00:50.840 --> 00:00:52.280
<v Speaker 2>without ever letting the circuit close.

16
00:00:52.520 --> 00:00:54.880
<v Speaker 1>The stakes literally do not get much higher than that.

17
00:00:55.079 --> 00:00:57.000
<v Speaker 1>So the mission of our deep dive today is to

18
00:00:57.039 --> 00:01:00.159
<v Speaker 1>equip you, the listener, with the specific toolkit and the

19
00:01:00.159 --> 00:01:03.840
<v Speaker 1>the analytical mindset used by reverse engineers to tear down iOS.

20
00:01:03.439 --> 00:01:06.000
<v Speaker 2>Apps entirely from the command line, which is the fun.

21
00:01:05.840 --> 00:01:08.799
<v Speaker 1>Part, right, We are going to unpack the methodology of

22
00:01:09.120 --> 00:01:10.519
<v Speaker 1>basic static analysis.

23
00:01:10.760 --> 00:01:13.719
<v Speaker 2>In today's progression, it really moves from the macro down

24
00:01:13.760 --> 00:01:17.640
<v Speaker 2>to the micro. We'll start by extracting the apps underlying

25
00:01:17.799 --> 00:01:22.319
<v Speaker 2>architectural blueprints from its MACO binary.

26
00:01:21.959 --> 00:01:24.040
<v Speaker 1>The fundamental building block exactly.

27
00:01:24.319 --> 00:01:27.840
<v Speaker 2>From there, we'll move into identifying its external library dependencies,

28
00:01:28.400 --> 00:01:31.439
<v Speaker 2>hunting down these little symbol breadcrumbs, and then we bring

29
00:01:31.480 --> 00:01:35.040
<v Speaker 2>in the heavy machinery to x ray the compiled assembly.

30
00:01:34.640 --> 00:01:37.879
<v Speaker 1>Code, which sounds intense, but we're going to break it

31
00:01:37.920 --> 00:01:38.319
<v Speaker 1>all down.

32
00:01:38.439 --> 00:01:40.280
<v Speaker 2>Yeah, and ultimately we're going to apply all of this

33
00:01:40.319 --> 00:01:44.079
<v Speaker 2>in a live, real world dissection of a really sophisticated,

34
00:01:44.239 --> 00:01:46.640
<v Speaker 2>completely hidden piece of iOS malware.

35
00:01:46.719 --> 00:01:48.599
<v Speaker 1>I cannot wait for that part. But let's start a

36
00:01:48.640 --> 00:01:52.280
<v Speaker 1>square one, because before we can reverse engineer the logic,

37
00:01:52.319 --> 00:01:55.640
<v Speaker 1>we have to profile the target, and in the Apple ecosystem,

38
00:01:55.680 --> 00:01:59.319
<v Speaker 1>that primarily means determining if the app relies on objective

39
00:01:59.359 --> 00:02:02.519
<v Speaker 1>CS or a bridged hybrid of the two.

40
00:02:02.439 --> 00:02:05.879
<v Speaker 2>Which is such a crucial first step because that distinction

41
00:02:06.079 --> 00:02:08.280
<v Speaker 2>changes your entire approach to the binary.

42
00:02:08.599 --> 00:02:11.039
<v Speaker 1>How So, like, why does the language matter that much?

43
00:02:11.080 --> 00:02:11.719
<v Speaker 1>Right out the gate?

44
00:02:11.879 --> 00:02:17.520
<v Speaker 2>Well, Swift by design incorporates really strict type safety and

45
00:02:17.680 --> 00:02:21.360
<v Speaker 2>module name spaces, and that forces the compiler to do

46
00:02:21.400 --> 00:02:22.639
<v Speaker 2>something called name mangling.

47
00:02:23.000 --> 00:02:26.080
<v Speaker 1>Name mangling. It sounds violent, it kind of is.

48
00:02:26.680 --> 00:02:31.159
<v Speaker 2>When the compiler processes those human readable Swift functions, it

49
00:02:31.240 --> 00:02:35.039
<v Speaker 2>compresses all that type and module information directly into the

50
00:02:35.039 --> 00:02:36.479
<v Speaker 2>function's internal symbol name.

51
00:02:36.879 --> 00:02:38.560
<v Speaker 1>Okay, so if I'm looking at it, it just looks

52
00:02:38.560 --> 00:02:41.400
<v Speaker 1>like complete cryptographic gibberish to the untrained eye.

53
00:02:41.439 --> 00:02:44.520
<v Speaker 2>Oh completely, it looks like random characters. Yeah, but it's

54
00:02:44.560 --> 00:02:46.719
<v Speaker 2>actually a highly structured naming convention.

55
00:02:47.000 --> 00:02:47.520
<v Speaker 1>Interesting.

56
00:02:47.680 --> 00:02:50.960
<v Speaker 2>So, if you are inspecting the dumped strings or symbols

57
00:02:50.960 --> 00:02:53.680
<v Speaker 2>of a binary and you spot a function declaration that

58
00:02:53.759 --> 00:02:56.199
<v Speaker 2>kicks off with an underscore followed by a capital T,

59
00:02:57.000 --> 00:03:00.759
<v Speaker 2>so that underscore T prefix, you have immediate conformation that

60
00:03:00.879 --> 00:03:02.439
<v Speaker 2>Swift is present in the codebase.

61
00:03:02.639 --> 00:03:06.400
<v Speaker 1>Oh okay, finding the underscore t prefix is a great heuristic.

62
00:03:06.719 --> 00:03:09.280
<v Speaker 1>But wait to even view those declarations in the first place,

63
00:03:09.520 --> 00:03:13.039
<v Speaker 1>we have to extract the structure from the compiled binary, right,

64
00:03:13.080 --> 00:03:15.199
<v Speaker 1>Because we aren't just reading flat text files here.

65
00:03:15.479 --> 00:03:18.280
<v Speaker 2>No. No, we rely on a command line utility called

66
00:03:18.319 --> 00:03:21.240
<v Speaker 2>class dump For that class dump. Yeah, it parses the

67
00:03:21.240 --> 00:03:25.560
<v Speaker 2>MACO file format, specifically targeting the objective C run time segments.

68
00:03:25.879 --> 00:03:28.919
<v Speaker 2>So it extracts the class headers, which basically gives you

69
00:03:28.960 --> 00:03:32.960
<v Speaker 2>the definitions of the objects, the properties, and the methods

70
00:03:32.960 --> 00:03:34.039
<v Speaker 2>that were compiled into the app.

71
00:03:34.159 --> 00:03:34.759
<v Speaker 1>Okay, got it.

72
00:03:34.800 --> 00:03:38.639
<v Speaker 2>But one really crucial operational note for anyone trying this,

73
00:03:39.520 --> 00:03:41.840
<v Speaker 2>you always want to use the most updated fork of

74
00:03:41.879 --> 00:03:45.199
<v Speaker 2>the tool. It's often maintained under the name class dumps.

75
00:03:45.360 --> 00:03:46.800
<v Speaker 1>Class dumps with an S.

76
00:03:47.199 --> 00:03:49.560
<v Speaker 2>Why is that Because the older iterations of it they

77
00:03:49.680 --> 00:03:53.319
<v Speaker 2>just choke and crash when they hit the complex metadata

78
00:03:53.319 --> 00:03:56.960
<v Speaker 2>structures generated by modern Swift compilers. They just can't handle it.

79
00:03:57.080 --> 00:03:59.560
<v Speaker 1>So using class dump is essentially like I don't know,

80
00:04:00.039 --> 00:04:02.800
<v Speaker 1>carrying the table of contents out of a book before

81
00:04:02.840 --> 00:04:05.840
<v Speaker 1>you read the chapters. Like you get the structural outline

82
00:04:05.840 --> 00:04:08.560
<v Speaker 1>without having to process the actual narrative flow.

83
00:04:08.719 --> 00:04:11.400
<v Speaker 2>That's a perfect analogy. It gives you the entire taxonomy

84
00:04:11.439 --> 00:04:12.879
<v Speaker 2>of the application at a glance.

85
00:04:13.240 --> 00:04:15.960
<v Speaker 1>Okay, I can definitely see the value in mapping the taxonomy,

86
00:04:17.199 --> 00:04:19.600
<v Speaker 1>But I got to push back slightly here. If we're

87
00:04:19.800 --> 00:04:23.319
<v Speaker 1>only looking at headers and method signatures, how much intent

88
00:04:23.480 --> 00:04:26.199
<v Speaker 1>can we actually infer? I mean, a table of contents

89
00:04:26.199 --> 00:04:28.240
<v Speaker 1>doesn't necessarily reveal a malicious plot.

90
00:04:28.040 --> 00:04:30.399
<v Speaker 2>Right You would be amazed at how much intent is

91
00:04:30.439 --> 00:04:35.199
<v Speaker 2>broadcast through class names alone. Wait really, oh absolutely? When

92
00:04:35.279 --> 00:04:39.600
<v Speaker 2>parsing those dumped headers, malware analysts are actively hunting for

93
00:04:39.680 --> 00:04:42.839
<v Speaker 2>specific high risk delegate.

94
00:04:42.399 --> 00:04:44.120
<v Speaker 1>Methods like what's a red flag?

95
00:04:44.279 --> 00:04:47.319
<v Speaker 2>Take handle open url for instance, Okay, spotting that immediately

96
00:04:47.319 --> 00:04:51.279
<v Speaker 2>tells you the application is registering custom URL schemes, which

97
00:04:51.319 --> 00:04:54.079
<v Speaker 2>means it's designed to be invoked by other apps or

98
00:04:54.120 --> 00:04:54.879
<v Speaker 2>by weblinks.

99
00:04:54.959 --> 00:04:57.360
<v Speaker 1>Oh, I see it's a doorway exactly, It's a potential

100
00:04:57.480 --> 00:05:00.839
<v Speaker 1>ingress point that immediately expands the attack surface. Yeah, because

101
00:05:00.839 --> 00:05:03.920
<v Speaker 1>of listening for inbound URLs. It could be you know,

102
00:05:03.959 --> 00:05:08.040
<v Speaker 1>receiving command payloads from somewhere else. What other system interactions

103
00:05:08.079 --> 00:05:10.839
<v Speaker 1>are we filtering for when we look at these headers.

104
00:05:10.439 --> 00:05:13.439
<v Speaker 2>Well, we always map the UI application delegate that helps

105
00:05:13.480 --> 00:05:16.399
<v Speaker 2>us understand the app's core life cycle hooks like what

106
00:05:16.439 --> 00:05:18.360
<v Speaker 2>does it do on launch? What does it do when

107
00:05:18.399 --> 00:05:21.480
<v Speaker 2>it's pushed to the background. But the real red flags

108
00:05:21.879 --> 00:05:23.879
<v Speaker 2>they often appear around web views.

109
00:05:23.759 --> 00:05:26.680
<v Speaker 1>Web views okay, so loading web pages inside the app.

110
00:05:26.519 --> 00:05:30.319
<v Speaker 2>Precisely, we actively hunt for UI WebView delegate or its

111
00:05:30.399 --> 00:05:33.480
<v Speaker 2>modern equivalents alongside NSR request.

112
00:05:33.839 --> 00:05:36.720
<v Speaker 1>So finding a UI WebView delegate combined with those request

113
00:05:36.759 --> 00:05:40.160
<v Speaker 1>classes means the application isn't just operating in a vacuum.

114
00:05:40.399 --> 00:05:43.920
<v Speaker 1>It has the actual plumbing to render remote web content

115
00:05:44.040 --> 00:05:47.879
<v Speaker 1>internally or I guess exfiltrate local data out to a

116
00:05:47.920 --> 00:05:48.519
<v Speaker 1>remote server.

117
00:05:48.759 --> 00:05:51.240
<v Speaker 2>You nailed it. It confirms a pathway to the Internet.

118
00:05:51.360 --> 00:05:53.439
<v Speaker 1>Wow. Okay, so just from the headers, we know it

119
00:05:53.480 --> 00:05:55.360
<v Speaker 1>can talk to the outside world exactly.

120
00:05:55.519 --> 00:05:59.439
<v Speaker 2>So now we've established the app's internal capabilities. But you know,

121
00:05:59.639 --> 00:06:03.720
<v Speaker 2>modern iOS applications, even the highly malicious ones, they rarely

122
00:06:03.759 --> 00:06:08.040
<v Speaker 2>reinvent the wheel. They rely on external frameworks to execute complex.

123
00:06:07.639 --> 00:06:11.240
<v Speaker 1>Tasks, which brings us to external dependencies. We have to

124
00:06:11.240 --> 00:06:13.439
<v Speaker 1>map out what the app intends to load into memory

125
00:06:13.480 --> 00:06:17.519
<v Speaker 1>at runtime. This transitions us to two specific command line utilities,

126
00:06:17.600 --> 00:06:19.879
<v Speaker 1>right otool and NM.

127
00:06:19.360 --> 00:06:24.319
<v Speaker 2>Yes, so otool is widely considered the fundamental utility for

128
00:06:24.399 --> 00:06:26.519
<v Speaker 2>inspecting Apple Maco binaries.

129
00:06:26.879 --> 00:06:29.319
<v Speaker 1>The Swiss Army knife basically.

130
00:06:28.959 --> 00:06:31.759
<v Speaker 2>Pretty much it reads the load commands that are embedded

131
00:06:31.800 --> 00:06:35.000
<v Speaker 2>right in the binary header, and those commands dictate exactly

132
00:06:35.040 --> 00:06:38.360
<v Speaker 2>how the operating system should map the executable into memory. Okay,

133
00:06:38.439 --> 00:06:40.920
<v Speaker 2>but the command flag you'll lean on most heavily here

134
00:06:41.079 --> 00:06:42.360
<v Speaker 2>is O tool.

135
00:06:42.240 --> 00:06:45.639
<v Speaker 1>Dash L and that's a capital L right, which flags

136
00:06:45.680 --> 00:06:48.759
<v Speaker 1>the tool to enumerate all the dynamically linked to libraries

137
00:06:48.800 --> 00:06:51.120
<v Speaker 1>the binary requires to actually function, right, and.

138
00:06:51.120 --> 00:06:53.879
<v Speaker 2>The output there gives you the exact paths to every

139
00:06:53.920 --> 00:06:57.600
<v Speaker 2>single shared library. Now, often you'll just see standard system

140
00:06:57.639 --> 00:07:00.519
<v Speaker 2>paths right, like Apples Foundation or UIKit frameworks.

141
00:07:00.560 --> 00:07:01.480
<v Speaker 1>Totally normal stuff.

142
00:07:01.519 --> 00:07:04.079
<v Speaker 2>Yeah, boring stuff. But the critical anomalies you want to

143
00:07:04.079 --> 00:07:07.439
<v Speaker 2>look for are dynamic paths, specifically ones heavily utilizing the

144
00:07:07.519 --> 00:07:08.519
<v Speaker 2>at our path.

145
00:07:08.319 --> 00:07:11.560
<v Speaker 1>Variable at our path the run path search path. That

146
00:07:11.639 --> 00:07:14.560
<v Speaker 1>is a highly abusable mechanism from what I understand, because

147
00:07:14.560 --> 00:07:17.399
<v Speaker 1>it tells the dynamic linker to resolve the library path

148
00:07:17.480 --> 00:07:20.879
<v Speaker 1>relative to where the application is currently running, rather than

149
00:07:21.480 --> 00:07:24.839
<v Speaker 1>relying on a hard coded absolute system path exactly.

150
00:07:24.920 --> 00:07:28.759
<v Speaker 2>And malware authors heavily leverage at our paths to sideload

151
00:07:29.079 --> 00:07:30.600
<v Speaker 2>malicious dynamic libraries.

152
00:07:30.680 --> 00:07:31.399
<v Speaker 1>Oh wow.

153
00:07:31.639 --> 00:07:35.360
<v Speaker 2>Yeah. By packaging a compromised dialib within the app's own

154
00:07:35.399 --> 00:07:38.839
<v Speaker 2>directory structure, they can basically trick the app into loading

155
00:07:38.839 --> 00:07:41.839
<v Speaker 2>their malicious code instead of a legitimate system library.

156
00:07:42.519 --> 00:07:45.360
<v Speaker 1>That is an elegant way to obscure the malicious payload

157
00:07:45.399 --> 00:07:48.759
<v Speaker 1>until the application actually spins up in memory it's hiding

158
00:07:48.759 --> 00:07:51.199
<v Speaker 1>in plain sight, it really is okay. So, once otol

159
00:07:51.199 --> 00:07:53.399
<v Speaker 1>has given us that dependency map and showed us where

160
00:07:53.439 --> 00:07:56.720
<v Speaker 1>it's looking for external code, we shift to analyzing the

161
00:07:56.759 --> 00:07:58.439
<v Speaker 1>symbols with MM.

162
00:07:58.160 --> 00:08:00.959
<v Speaker 2>Right, because while otool can dumps symbols, if you use

163
00:08:01.000 --> 00:08:05.759
<v Speaker 2>specific flags like dash, ODAV and M is explicitly built

164
00:08:05.759 --> 00:08:09.560
<v Speaker 2>for this. It parses and displays the symbol table of

165
00:08:09.560 --> 00:08:10.839
<v Speaker 2>a binary.

166
00:08:10.519 --> 00:08:12.959
<v Speaker 1>And just clarify for everyone. The symbol table contains the

167
00:08:13.040 --> 00:08:15.519
<v Speaker 1>names and addresses of all the functions and global variables

168
00:08:15.519 --> 00:08:18.319
<v Speaker 1>the program uses, right, including the ones it expects to find.

169
00:08:18.360 --> 00:08:21.160
<v Speaker 1>Those dynamic libraries we just mapped out exactly. So if

170
00:08:21.160 --> 00:08:23.759
<v Speaker 1>O'Toole tells us where the app is looking for external code,

171
00:08:23.800 --> 00:08:26.160
<v Speaker 1>and M tells us what specific functions it plans to

172
00:08:26.199 --> 00:08:27.879
<v Speaker 1>call from that code, right.

173
00:08:27.920 --> 00:08:31.959
<v Speaker 2>You are looking at the unresolved references left behind by

174
00:08:31.959 --> 00:08:35.519
<v Speaker 2>the developer. It essentially becomes a targeted hunting expedition. At

175
00:08:35.519 --> 00:08:38.600
<v Speaker 2>that point, you dump the symbols and you filter for

176
00:08:38.679 --> 00:08:39.960
<v Speaker 2>high risk system calls.

177
00:08:40.399 --> 00:08:43.039
<v Speaker 1>Give me an example of that. What's a specific symbol

178
00:08:43.080 --> 00:08:45.679
<v Speaker 1>that spikes your threat radar during static analysis?

179
00:08:45.720 --> 00:08:48.759
<v Speaker 2>Oh, A prime example is MEMCPI, MENPI Okay, it's a

180
00:08:48.799 --> 00:08:52.200
<v Speaker 2>standard C library function for moving blocks of memory, but

181
00:08:52.519 --> 00:08:55.639
<v Speaker 2>it notoriously lacks boundary checking.

182
00:08:55.879 --> 00:08:57.440
<v Speaker 1>Ah, I see where this is going.

183
00:08:57.519 --> 00:09:02.039
<v Speaker 2>Right. If we observe a binary aggressively utilizing mengpie, especially

184
00:09:02.080 --> 00:09:04.679
<v Speaker 2>if it's doing it in close proximity to network socket

185
00:09:04.759 --> 00:09:08.919
<v Speaker 2>operations or parsing untrusted data, we're very likely looking at

186
00:09:08.919 --> 00:09:11.879
<v Speaker 2>the foundational mechanics of a buffer overflow exploit.

187
00:09:12.080 --> 00:09:14.279
<v Speaker 1>Wow. Okay, so that's a huge red flag.

188
00:09:14.120 --> 00:09:17.320
<v Speaker 2>A massive one. We also actively scan for functions like

189
00:09:17.440 --> 00:09:20.320
<v Speaker 2>c trace, which malware frequently uses to detect if it's

190
00:09:20.320 --> 00:09:21.639
<v Speaker 2>being monitored by a debugger.

191
00:09:21.840 --> 00:09:24.960
<v Speaker 1>Sneaky. Okay. So at this point, the internal blueprints are map,

192
00:09:25.080 --> 00:09:28.080
<v Speaker 1>the dynamic libraries are enumerated, and the simple tables are parsed.

193
00:09:28.159 --> 00:09:30.440
<v Speaker 1>We have a lot of data, but so far we're

194
00:09:30.480 --> 00:09:33.559
<v Speaker 1>just looking at lists of metadata and function pointer, just

195
00:09:33.720 --> 00:09:37.879
<v Speaker 1>pieces of the puzzle exactly. To understand the actual execution flow,

196
00:09:38.080 --> 00:09:41.200
<v Speaker 1>like the underlying logic of the malware, we have to

197
00:09:41.240 --> 00:09:44.759
<v Speaker 1>translate the compiled binary back into something readable. We need

198
00:09:44.759 --> 00:09:45.799
<v Speaker 1>the X ray machine.

199
00:09:45.919 --> 00:09:48.919
<v Speaker 2>Yes, we need to pull back the curtain on the

200
00:09:48.960 --> 00:09:52.960
<v Speaker 2>actual machine code. And this is where disassemblers like Hopper

201
00:09:53.120 --> 00:09:56.360
<v Speaker 2>or Ida pro become completely indispensable.

202
00:09:56.559 --> 00:09:56.679
<v Speaker 1>Right.

203
00:09:56.840 --> 00:10:00.279
<v Speaker 2>They parse the compiled ARM sixty four op codes and

204
00:10:00.320 --> 00:10:03.720
<v Speaker 2>they translate them back into human readable assembly mnemonics.

205
00:10:03.919 --> 00:10:07.279
<v Speaker 1>So a disassembler is essentially a universal translator. It takes

206
00:10:07.320 --> 00:10:09.720
<v Speaker 1>the ones and zeros that only the processor understands and

207
00:10:09.799 --> 00:10:15.200
<v Speaker 1>reconstructs the logic branches, the register assignments, and memory allocations exactly.

208
00:10:15.600 --> 00:10:19.440
<v Speaker 2>And translating ARM sixty four architecture is incredibly complex, I mean,

209
00:10:19.559 --> 00:10:22.000
<v Speaker 2>just due to the sheer volume of registers and the

210
00:10:22.000 --> 00:10:25.519
<v Speaker 2>intricacies of its branching logic. But a tool like Hopper

211
00:10:25.559 --> 00:10:28.759
<v Speaker 2>excels at making this approachable for analysts.

212
00:10:28.360 --> 00:10:31.759
<v Speaker 1>And for those who haven't worked inside a dedicated disassembly environment.

213
00:10:31.840 --> 00:10:34.919
<v Speaker 1>Hopper provides a really highly visual workspace. It isn't just

214
00:10:35.600 --> 00:10:37.480
<v Speaker 1>a terminal window of scrolling.

215
00:10:37.080 --> 00:10:38.320
<v Speaker 2>Texts none of all.

216
00:10:38.360 --> 00:10:41.279
<v Speaker 1>You get a control flow graph which visually represents the

217
00:10:41.279 --> 00:10:45.200
<v Speaker 1>code as branching blocks connected by logic pathways. You can

218
00:10:45.279 --> 00:10:48.840
<v Speaker 1>literally see how an IFL statement splits the execution into

219
00:10:48.879 --> 00:10:50.000
<v Speaker 1>different memory addresses.

220
00:10:50.559 --> 00:10:53.720
<v Speaker 2>The visual representation is invaluable, I mean, it saves so

221
00:10:53.799 --> 00:10:57.399
<v Speaker 2>much time. But honestly, the most powerful feature in Hopper

222
00:10:57.759 --> 00:11:00.720
<v Speaker 2>for rapid static analysis is the strings window.

223
00:11:00.919 --> 00:11:02.120
<v Speaker 1>The strings window.

224
00:11:02.240 --> 00:11:05.720
<v Speaker 2>Yeah, it consolidates all the hard coded plaintext that's embedded

225
00:11:05.759 --> 00:11:07.240
<v Speaker 2>anywhere in the buying area, which.

226
00:11:07.039 --> 00:11:09.960
<v Speaker 1>Allows for immediate cross referencing. So if I run a

227
00:11:09.960 --> 00:11:12.960
<v Speaker 1>search and Hopper for this string HTTP, I don't just

228
00:11:13.000 --> 00:11:15.679
<v Speaker 1>see the text, right, I can use the cross reference

229
00:11:15.720 --> 00:11:19.039
<v Speaker 1>feature the XRAS to jump directly to the exact memory

230
00:11:19.039 --> 00:11:21.080
<v Speaker 1>address where that string is loaded into a register.

231
00:11:21.279 --> 00:11:24.759
<v Speaker 2>Exactly that workflow. Right there is the core of static analysis.

232
00:11:24.960 --> 00:11:27.799
<v Speaker 2>You find a suspicious string, you track its cross reference

233
00:11:27.840 --> 00:11:31.159
<v Speaker 2>to a specific subroutine, and suddenly you are looking at

234
00:11:31.200 --> 00:11:35.519
<v Speaker 2>the exact logic block responsible for, say xfiltrating data to

235
00:11:35.559 --> 00:11:36.759
<v Speaker 2>a command and control server.

236
00:11:36.879 --> 00:11:37.840
<v Speaker 1>That is incredible.

237
00:11:38.080 --> 00:11:41.639
<v Speaker 2>And if reading raw ARM sixty four assembly proves two

238
00:11:41.720 --> 00:11:45.360
<v Speaker 2>time consuming, which it offered does. Hopper features a pseudo

239
00:11:45.360 --> 00:11:49.279
<v Speaker 2>code decompiler with a single click, it attempts to reconstruct

240
00:11:49.320 --> 00:11:52.720
<v Speaker 2>the assembly back into a C like high level language.

241
00:11:52.360 --> 00:11:56.440
<v Speaker 1>Which just accelerates the deep code analysis exponentially. Okay, so

242
00:11:56.679 --> 00:11:59.360
<v Speaker 1>we have covered the conceptual framework. We've got the entire

243
00:11:59.399 --> 00:12:02.279
<v Speaker 1>command line toolchain down. It's time to move from theory

244
00:12:02.480 --> 00:12:03.240
<v Speaker 1>to application.

245
00:12:03.480 --> 00:12:03.960
<v Speaker 2>Let's do it.

246
00:12:04.039 --> 00:12:06.720
<v Speaker 1>We have an unanalyzed file sitting in our sandbox right now,

247
00:12:06.879 --> 00:12:10.639
<v Speaker 1>and it is literally labeled malware dot IPA. We are

248
00:12:10.679 --> 00:12:14.200
<v Speaker 1>going to execute a live zero knowledge takedown of this

249
00:12:14.360 --> 00:12:15.879
<v Speaker 1>black box. Walk me through it.

250
00:12:15.960 --> 00:12:18.919
<v Speaker 2>Okay. So the initial protocol for any unknown binary is

251
00:12:18.960 --> 00:12:21.960
<v Speaker 2>generating a cryptographic hash. We need to check it against

252
00:12:22.000 --> 00:12:23.759
<v Speaker 2>known threat intelligence databases.

253
00:12:23.840 --> 00:12:26.440
<v Speaker 1>Okay, So I'm calculating the MD five and SAHA two

254
00:12:26.519 --> 00:12:28.679
<v Speaker 1>hundred fifty six hashes of the file right now. See

255
00:12:28.799 --> 00:12:31.519
<v Speaker 1>let's query virus Total and see what the global scanners

256
00:12:31.519 --> 00:12:34.600
<v Speaker 1>say about this thing. Now, the results are completely negative,

257
00:12:34.720 --> 00:12:38.120
<v Speaker 1>zero hits across all vendors. Virus Total has never seen it.

258
00:12:38.440 --> 00:12:41.559
<v Speaker 2>Okay, So we are dealing with a zero day here,

259
00:12:41.799 --> 00:12:44.200
<v Speaker 2>or at least a highly targeted payload that just hasn't

260
00:12:44.200 --> 00:12:47.879
<v Speaker 2>been widely distributed yet. Right. Threat intelligence is totally blind here,

261
00:12:48.080 --> 00:12:51.159
<v Speaker 2>which means we have to rely entirely on our static

262
00:12:51.240 --> 00:12:53.759
<v Speaker 2>analysis toolchain to figure out what this thing does. So

263
00:12:53.840 --> 00:12:54.679
<v Speaker 2>let's pry it open.

264
00:12:54.759 --> 00:12:58.600
<v Speaker 1>Okay. I'm unzipping the dot ipa archive and it reveals

265
00:12:58.639 --> 00:13:01.600
<v Speaker 1>the standard iOS application bundle structure.

266
00:13:01.759 --> 00:13:04.559
<v Speaker 2>Right. So, navigating into the payload directory, our first goal

267
00:13:04.639 --> 00:13:09.799
<v Speaker 2>is to locate the primary MACO executable, but relying on

268
00:13:09.840 --> 00:13:13.360
<v Speaker 2>the visual filenames in that directory is a really common pitfall.

269
00:13:13.559 --> 00:13:14.559
<v Speaker 1>Oh why is that?

270
00:13:15.000 --> 00:13:18.279
<v Speaker 2>Well, the outer wrapper might be named malware or something obvious,

271
00:13:18.360 --> 00:13:21.600
<v Speaker 2>but the internal binary often utilizes a completely different naming

272
00:13:21.639 --> 00:13:23.919
<v Speaker 2>convention just to avoid casual detection.

273
00:13:24.360 --> 00:13:27.440
<v Speaker 1>Uh okay, So to find the definitive entry point, we

274
00:13:27.480 --> 00:13:31.320
<v Speaker 1>shouldn't just guess. We query the infodot plist file using

275
00:13:31.360 --> 00:13:35.000
<v Speaker 1>the plutal command, and by reading the cf bundle executable key,

276
00:13:35.360 --> 00:13:37.799
<v Speaker 1>we bypass any of that directory obfuscation.

277
00:13:37.960 --> 00:13:39.320
<v Speaker 2>So what does the property list say?

278
00:13:39.360 --> 00:13:41.679
<v Speaker 1>Okay, looking at it now, it reveals the true executable

279
00:13:41.720 --> 00:13:45.000
<v Speaker 1>is named no icon no icon. Yeah, no icon.

280
00:13:45.200 --> 00:13:47.919
<v Speaker 2>Well that immediately implies a conscious effort at stealth.

281
00:13:48.120 --> 00:13:51.039
<v Speaker 1>Definitely. Okay, we have our target binary. Let's pipe the

282
00:13:51.039 --> 00:13:55.639
<v Speaker 1>strings command through GRIP and filter specifically for HTTP to

283
00:13:55.639 --> 00:13:59.080
<v Speaker 1>see if this binary contains hard coded network infrastructure.

284
00:13:59.200 --> 00:14:00.399
<v Speaker 2>We'll see what it's fit out.

285
00:14:00.799 --> 00:14:06.000
<v Speaker 1>WHOA, The terminal output is massive. We are looking at

286
00:14:06.000 --> 00:14:10.759
<v Speaker 1>a really dense list of domains, ip addresses, specific uripaths.

287
00:14:10.840 --> 00:14:11.120
<v Speaker 2>Wow.

288
00:14:11.639 --> 00:14:15.360
<v Speaker 1>Yeah, Despite being entirely unknown to the anti virus scanners,

289
00:14:15.600 --> 00:14:19.799
<v Speaker 1>this application is hardwired to communicate with dozens of external endpoints.

290
00:14:19.879 --> 00:14:23.000
<v Speaker 2>It's hitting a massive variety of infrastructure, which is very telling.

291
00:14:23.159 --> 00:14:26.200
<v Speaker 2>This points toward either a domain generation algorithm for command

292
00:14:26.279 --> 00:14:28.840
<v Speaker 2>and control or it's cycling through a hard coded list

293
00:14:28.840 --> 00:14:30.279
<v Speaker 2>of drop sites to see what's active.

294
00:14:30.519 --> 00:14:32.759
<v Speaker 1>Let's dig a little deeper into the broader string stump.

295
00:14:32.799 --> 00:14:34.639
<v Speaker 1>Then what else is embedded in this binary?

296
00:14:34.879 --> 00:14:38.440
<v Speaker 2>Okay, Filtering past all those URLs, we uncover some highly

297
00:14:38.480 --> 00:14:42.200
<v Speaker 2>specific operational plaintext. Look at this, there are distinct references

298
00:14:42.240 --> 00:14:45.639
<v Speaker 2>to an ad page component at page yeah. And more critically,

299
00:14:45.639 --> 00:14:48.960
<v Speaker 2>we find strings querying for no icon update and active

300
00:14:49.000 --> 00:14:52.200
<v Speaker 2>filepath checks looking for other dot IBA packages stored locally

301
00:14:52.200 --> 00:14:53.000
<v Speaker 2>on the file system.

302
00:14:53.279 --> 00:14:56.919
<v Speaker 1>Wait, looking for other apps. Let's synthesize those artifacts. We

303
00:14:57.000 --> 00:15:00.960
<v Speaker 1>have aggressive network requests, references to ap tizing components, and

304
00:15:01.000 --> 00:15:05.000
<v Speaker 1>mechanisms designed to search for and update secondary IYP of files.

305
00:15:05.840 --> 00:15:09.600
<v Speaker 1>The primary binary is a stager. It's a dropper. It's

306
00:15:09.600 --> 00:15:13.240
<v Speaker 1>designed to quietly pull down and install adware or you

307
00:15:13.279 --> 00:15:15.879
<v Speaker 1>know more destructive secondary payloads in the background.

308
00:15:15.960 --> 00:15:21.720
<v Speaker 2>Exactly. The behavioral profile strongly aligns with a dropper. But

309
00:15:21.879 --> 00:15:23.919
<v Speaker 2>and this is key for a dropper to be effective

310
00:15:23.960 --> 00:15:27.039
<v Speaker 2>on iOS, it has to persist on the device long

311
00:15:27.159 --> 00:15:30.399
<v Speaker 2>enough to actually execute those secondary downloads.

312
00:15:29.960 --> 00:15:31.919
<v Speaker 1>Which means it needs to avoid user detection.

313
00:15:32.159 --> 00:15:33.759
<v Speaker 2>Right, it can't look suspicious.

314
00:15:33.879 --> 00:15:36.799
<v Speaker 1>Let's check how it masks its presence. Returning to the

315
00:15:36.799 --> 00:15:39.879
<v Speaker 1>plutal tool, I'll extract the cf bundle display name from

316
00:15:39.919 --> 00:15:42.279
<v Speaker 1>the infodoup plus what did they name it? The developer

317
00:15:42.279 --> 00:15:46.440
<v Speaker 1>has set the display name to passbook, masquerading as a

318
00:15:46.519 --> 00:15:48.320
<v Speaker 1>legacy Apple Wallet component.

319
00:15:48.600 --> 00:15:50.440
<v Speaker 2>That is incredible calculated.

320
00:15:50.720 --> 00:15:53.519
<v Speaker 1>It really is, because if a user happens to glance

321
00:15:53.559 --> 00:15:57.120
<v Speaker 1>at their battery usage or their network settings, seeing Passbook

322
00:15:57.200 --> 00:16:01.039
<v Speaker 1>consuming resources isn't likely to trigger immediate alarm. It just

323
00:16:01.120 --> 00:16:03.440
<v Speaker 1>blends right into the expected system noise.

324
00:16:03.519 --> 00:16:06.960
<v Speaker 2>Yeah, nobody questions pastbook. But the disguise actually goes deeper

325
00:16:07.000 --> 00:16:10.000
<v Speaker 2>than just the display name. Let's extract the seaf bundle

326
00:16:10.000 --> 00:16:11.879
<v Speaker 2>identifier from that same property list.

327
00:16:12.000 --> 00:16:15.360
<v Speaker 1>Okay, pulling that up, the identifier is calm dot wheeling

328
00:16:15.440 --> 00:16:18.159
<v Speaker 1>dot hidden dot icon dot onian dot launch.

329
00:16:18.480 --> 00:16:21.200
<v Speaker 2>The developer naming conventions are surprisingly brazen.

330
00:16:21.200 --> 00:16:24.240
<v Speaker 1>There seriously hidden icon on launch.

331
00:16:24.399 --> 00:16:29.120
<v Speaker 2>Yeah, but the critical element is the configuration flag attached

332
00:16:29.159 --> 00:16:32.159
<v Speaker 2>to that bundle identifier. Look at the status flag. It

333
00:16:32.240 --> 00:16:35.399
<v Speaker 2>is explicitly configured to hidden hidden.

334
00:16:35.480 --> 00:16:38.759
<v Speaker 1>So wait, by manipulating that specific property list key, the

335
00:16:38.799 --> 00:16:42.320
<v Speaker 1>application is instructing the iOS springboard demon which is the

336
00:16:42.360 --> 00:16:45.679
<v Speaker 1>process responsible for managing the home screen UI. Right. Yeah,

337
00:16:45.720 --> 00:16:48.600
<v Speaker 1>it's instructing it to completely ignore the app's existence.

338
00:16:48.639 --> 00:16:51.120
<v Speaker 2>That's exactly what it's doing. The icon is literally never

339
00:16:51.159 --> 00:16:51.960
<v Speaker 2>rendered on the screen.

340
00:16:52.039 --> 00:16:56.080
<v Speaker 1>Oh my god. It achieves near perfect persistence purely through

341
00:16:56.240 --> 00:16:57.919
<v Speaker 1>a UI configuration trick.

342
00:16:58.279 --> 00:17:01.000
<v Speaker 2>Yeah, there is nothing for the user to tack and crucially,

343
00:17:01.080 --> 00:17:03.120
<v Speaker 2>there's nothing for the user to long press and delete.

344
00:17:03.279 --> 00:17:07.839
<v Speaker 1>Wow. It operates as an invisible, silent stager. That is

345
00:17:08.240 --> 00:17:12.440
<v Speaker 1>brilliantly devious. Well, okay, there's one final artifact we need

346
00:17:12.480 --> 00:17:16.240
<v Speaker 1>to map for this profile. What language was this dropper

347
00:17:16.319 --> 00:17:17.119
<v Speaker 1>compiled from?

348
00:17:17.680 --> 00:17:21.319
<v Speaker 2>Good question. So we execute total dash L against the

349
00:17:21.319 --> 00:17:25.200
<v Speaker 2>no icon binary, and we filtered the dynamic library output

350
00:17:25.240 --> 00:17:28.039
<v Speaker 2>for any reliance on Swift foundation frameworks.

351
00:17:27.640 --> 00:17:30.559
<v Speaker 1>Right, looking for that underscore t signature exactly.

352
00:17:30.799 --> 00:17:32.960
<v Speaker 2>We are checking for that name mangling signature in the

353
00:17:33.000 --> 00:17:36.079
<v Speaker 2>symbols as well, and the results entirely void. There are

354
00:17:36.079 --> 00:17:39.880
<v Speaker 2>no Swift dependencies and the classheaders show zero Swift taxonomy.

355
00:17:40.119 --> 00:17:43.559
<v Speaker 1>So the dropper is written entirely in pure objective C

356
00:17:43.920 --> 00:17:47.200
<v Speaker 1>completely which structurally that makes a lot of sense. I mean,

357
00:17:47.240 --> 00:17:49.599
<v Speaker 1>if your goal is to build a stealthy dropper that

358
00:17:49.640 --> 00:17:54.200
<v Speaker 1>can maximize its compatibility across older, potentially vulnerable iterations of iOS.

359
00:17:54.559 --> 00:17:57.240
<v Speaker 1>Writing it in objective c ensures it can execute without

360
00:17:57.240 --> 00:17:59.000
<v Speaker 1>requiring modern runtime environments.

361
00:17:59.279 --> 00:18:02.720
<v Speaker 2>Exactly you wanted to run on as many devices as possible. Yeah,

362
00:18:02.759 --> 00:18:05.400
<v Speaker 2>and that takedown right there is a perfect illustration of

363
00:18:05.440 --> 00:18:06.200
<v Speaker 2>the methodology.

364
00:18:06.319 --> 00:18:10.680
<v Speaker 1>It really is. We approached an entirely undocumented zero day

365
00:18:10.720 --> 00:18:14.559
<v Speaker 1>threat and without ever risking execution. We mapped its C

366
00:18:14.720 --> 00:18:20.640
<v Speaker 1>two infrastructure, identified its true executable, uncovered its stager functionality,

367
00:18:21.160 --> 00:18:23.680
<v Speaker 1>and analyzed its UI evasion techniques.

368
00:18:23.799 --> 00:18:26.880
<v Speaker 2>It just proves that a disciplined, structured approach to static

369
00:18:26.920 --> 00:18:30.480
<v Speaker 2>analysis can force any binary to revealed core architecture.

370
00:18:30.519 --> 00:18:33.200
<v Speaker 1>He just had to know where to look, absolutely so.

371
00:18:33.440 --> 00:18:36.880
<v Speaker 1>To synthesize the toolkit for everyone listening, we utilized class

372
00:18:36.880 --> 00:18:40.400
<v Speaker 1>stump to extract the objective C run time taxonomy and headers.

373
00:18:40.720 --> 00:18:43.480
<v Speaker 1>We leveraged O tool to map the macho load commands

374
00:18:43.480 --> 00:18:46.480
<v Speaker 1>and external dynamic libraries, paying special attention to that at

375
00:18:46.519 --> 00:18:49.599
<v Speaker 1>our path abuse. We employed enronment to parts the symbol

376
00:18:49.640 --> 00:18:53.559
<v Speaker 1>tables for exploitable C functions. We vitualized the ARM sixty

377
00:18:53.559 --> 00:18:57.400
<v Speaker 1>four control flow graphs using Hopper, and finally we extracted

378
00:18:57.440 --> 00:19:01.039
<v Speaker 1>strings and propertyless configurations to completely dismantle a live dropper.

379
00:19:01.119 --> 00:19:02.839
<v Speaker 2>A very successful mission definitely.

380
00:19:03.000 --> 00:19:05.640
<v Speaker 1>Now to lock in this methodology, let's run a rapid

381
00:19:05.680 --> 00:19:09.599
<v Speaker 1>review scenario for you listening pop quiz. If you suspect

382
00:19:09.640 --> 00:19:13.960
<v Speaker 1>a newly intercepted iOS application is covertly rendering remote web content,

383
00:19:14.359 --> 00:19:17.559
<v Speaker 1>which command line utility provides the dependency map and what

384
00:19:17.759 --> 00:19:21.759
<v Speaker 1>specific class header validates that web functionality, Well, you would.

385
00:19:21.599 --> 00:19:24.880
<v Speaker 2>Run O tool dash L to map the dynamic library dependencies,

386
00:19:25.200 --> 00:19:28.319
<v Speaker 2>and you would parse the class dump output, specifically hunting

387
00:19:28.319 --> 00:19:30.440
<v Speaker 2>for the UI WebView delegate.

388
00:19:30.000 --> 00:19:33.759
<v Speaker 1>Class spot on. Now, the mechanics of our takedown today

389
00:19:33.839 --> 00:19:38.640
<v Speaker 1>highlight just how effectively malware can weaponize standard configuration files

390
00:19:38.680 --> 00:19:41.759
<v Speaker 1>like the info dot plist to achieve total invisibility on

391
00:19:41.799 --> 00:19:42.240
<v Speaker 1>a device.

392
00:19:42.480 --> 00:19:43.839
<v Speaker 2>It's scary how simple it can be.

393
00:19:44.000 --> 00:19:47.880
<v Speaker 1>It is, but as we master these manual static analysis techniques,

394
00:19:47.920 --> 00:19:50.559
<v Speaker 1>we have to acknowledge that the defensive landscape is fundamentally

395
00:19:50.559 --> 00:19:53.400
<v Speaker 1>shifting beneath us. I mean, we just spent this entire

396
00:19:53.559 --> 00:19:58.480
<v Speaker 1>session manually tracing op codes, cross referencing strings, and parsing macoheaders.

397
00:19:58.559 --> 00:19:59.960
<v Speaker 2>Right, taking it step by step.

398
00:20:00.119 --> 00:20:03.720
<v Speaker 1>But consider the current trajectory of large language models. We

399
00:20:03.759 --> 00:20:06.319
<v Speaker 1>are rapidly approaching an inflection point where you could just

400
00:20:06.359 --> 00:20:10.759
<v Speaker 1>feed a fully compiled, highly obfuscated MACO binary directly into

401
00:20:10.799 --> 00:20:13.920
<v Speaker 1>a specialized AI model. Oh wow, and the AI will

402
00:20:13.920 --> 00:20:18.279
<v Speaker 1>instantly decompile the ARM sixty four architecture map, the control

403
00:20:18.319 --> 00:20:22.400
<v Speaker 1>flow graphs, cross reference the network infrastructure, and output a

404
00:20:22.440 --> 00:20:27.400
<v Speaker 1>comprehensive zero day behavioral analysis in seconds, in seconds, seconds.

405
00:20:27.519 --> 00:20:31.680
<v Speaker 1>It completely automates the meticulous manual detective work we just covered,

406
00:20:31.799 --> 00:20:35.799
<v Speaker 1>So it begs the question, as AI effortlessly unravels even

407
00:20:35.799 --> 00:20:40.079
<v Speaker 1>the most sophisticated compiled binaries, will human reverse engineers be

408
00:20:40.119 --> 00:20:43.359
<v Speaker 1>rendered obsolete or simply elevated to architects of entirely new

409
00:20:43.480 --> 00:20:45.000
<v Speaker 1>automated defense paradigms.

410
00:20:45.039 --> 00:20:47.839
<v Speaker 2>Man it is a profound paradigm shift. The barrier to

411
00:20:47.880 --> 00:20:51.319
<v Speaker 2>deep technical analysis is dissolving, which means the speed of

412
00:20:51.319 --> 00:20:54.799
<v Speaker 2>both offense and defense is about to accelerate exponentially.

413
00:20:55.000 --> 00:20:57.480
<v Speaker 1>It is a transformative horizon to keep your eyes on.

414
00:20:57.559 --> 00:21:00.839
<v Speaker 1>But until then, master the fundamentals, trust the architecture over

415
00:21:00.839 --> 00:21:02.480
<v Speaker 1>the interface, and keep diving deep
