Speaker 1: Imagine you've just intercepted this highly suspicious iOS application file.
Speaker 1: It's just sitting right there in your sandbox, effectively, you know,
Speaker 1: a locked black box right just waiting to be opened exactly,
Speaker 1: and you need to know its exact capabilities, like what's
Speaker 1: its network infrastructure? What is the ultimate payload here?
Speaker 2: Which you can't just double click it?
Speaker 1: No, absolutely not running it. Actually executing that file on
Speaker 1: a test device could unleash absolute chaos, I mean, potentially
Speaker 1: burning your entire analysis environment, or even worse, alerting the
Speaker 1: malware's command and control servers that you're actively watching them.
Speaker 2: Yeah, it's basically the ultimate digital bomb disposal scenario. It
Speaker 2: really is your task with mapping the internal wiring, analyzing
Speaker 2: the chemical composition of the explosive, and you know, tracing
Speaker 2: the detonator. But you have to do all of that
Speaker 2: without ever letting the circuit close.
Speaker 1: The stakes literally do not get much higher than that.
Speaker 1: So the mission of our deep dive today is to
Speaker 1: equip you, the listener, with the specific toolkit and the
Speaker 1: the analytical mindset used by reverse engineers to tear down iOS.
Speaker 2: Apps entirely from the command line, which is the fun.
Speaker 1: Part, right, We are going to unpack the methodology of
Speaker 1: basic static analysis.
Speaker 2: In today's progression, it really moves from the macro down
Speaker 2: to the micro. We'll start by extracting the apps underlying
Speaker 2: architectural blueprints from its MACO binary.
Speaker 1: The fundamental building block exactly.
Speaker 2: From there, we'll move into identifying its external library dependencies,
Speaker 2: hunting down these little symbol breadcrumbs, and then we bring
Speaker 2: in the heavy machinery to x ray the compiled assembly.
Speaker 1: Code, which sounds intense, but we're going to break it
Speaker 1: all down.
Speaker 2: Yeah, and ultimately we're going to apply all of this
Speaker 2: in a live, real world dissection of a really sophisticated,
Speaker 2: completely hidden piece of iOS malware.
Speaker 1: I cannot wait for that part. But let's start a
Speaker 1: square one, because before we can reverse engineer the logic,
Speaker 1: we have to profile the target, and in the Apple ecosystem,
Speaker 1: that primarily means determining if the app relies on objective
Speaker 1: CS or a bridged hybrid of the two.
Speaker 2: Which is such a crucial first step because that distinction
Speaker 2: changes your entire approach to the binary.
Speaker 1: How So, like, why does the language matter that much?
Speaker 1: Right out the gate?
Speaker 2: Well, Swift by design incorporates really strict type safety and
Speaker 2: module name spaces, and that forces the compiler to do
Speaker 2: something called name mangling.
Speaker 1: Name mangling. It sounds violent, it kind of is.
Speaker 2: When the compiler processes those human readable Swift functions, it
Speaker 2: compresses all that type and module information directly into the
Speaker 2: function's internal symbol name.
Speaker 1: Okay, so if I'm looking at it, it just looks
Speaker 1: like complete cryptographic gibberish to the untrained eye.
Speaker 2: Oh completely, it looks like random characters. Yeah, but it's
Speaker 2: actually a highly structured naming convention.
Speaker 1: Interesting.
Speaker 2: So, if you are inspecting the dumped strings or symbols
Speaker 2: of a binary and you spot a function declaration that
Speaker 2: kicks off with an underscore followed by a capital T,
Speaker 2: so that underscore T prefix, you have immediate conformation that
Speaker 2: Swift is present in the codebase.
Speaker 1: Oh okay, finding the underscore t prefix is a great heuristic.
Speaker 1: But wait to even view those declarations in the first place,
Speaker 1: we have to extract the structure from the compiled binary, right,
Speaker 1: Because we aren't just reading flat text files here.
Speaker 2: No. No, we rely on a command line utility called
Speaker 2: class dump For that class dump. Yeah, it parses the
Speaker 2: MACO file format, specifically targeting the objective C run time segments.
Speaker 2: So it extracts the class headers, which basically gives you
Speaker 2: the definitions of the objects, the properties, and the methods
Speaker 2: that were compiled into the app.
Speaker 1: Okay, got it.
Speaker 2: But one really crucial operational note for anyone trying this,
Speaker 2: you always want to use the most updated fork of
Speaker 2: the tool. It's often maintained under the name class dumps.
Speaker 1: Class dumps with an S.
Speaker 2: Why is that Because the older iterations of it they
Speaker 2: just choke and crash when they hit the complex metadata
Speaker 2: structures generated by modern Swift compilers. They just can't handle it.
Speaker 1: So using class dump is essentially like I don't know,
Speaker 1: carrying the table of contents out of a book before
Speaker 1: you read the chapters. Like you get the structural outline
Speaker 1: without having to process the actual narrative flow.
Speaker 2: That's a perfect analogy. It gives you the entire taxonomy
Speaker 2: of the application at a glance.
Speaker 1: Okay, I can definitely see the value in mapping the taxonomy,
Speaker 1: But I got to push back slightly here. If we're
Speaker 1: only looking at headers and method signatures, how much intent
Speaker 1: can we actually infer? I mean, a table of contents
Speaker 1: doesn't necessarily reveal a malicious plot.
Speaker 2: Right You would be amazed at how much intent is
Speaker 2: broadcast through class names alone. Wait really, oh absolutely? When
Speaker 2: parsing those dumped headers, malware analysts are actively hunting for
Speaker 2: specific high risk delegate.
Speaker 1: Methods like what's a red flag?
Speaker 2: Take handle open url for instance, Okay, spotting that immediately
Speaker 2: tells you the application is registering custom URL schemes, which
Speaker 2: means it's designed to be invoked by other apps or
Speaker 2: by weblinks.
Speaker 1: Oh, I see it's a doorway exactly, It's a potential
Speaker 1: ingress point that immediately expands the attack surface. Yeah, because
Speaker 1: of listening for inbound URLs. It could be you know,
Speaker 1: receiving command payloads from somewhere else. What other system interactions
Speaker 1: are we filtering for when we look at these headers.
Speaker 2: Well, we always map the UI application delegate that helps
Speaker 2: us understand the app's core life cycle hooks like what
Speaker 2: does it do on launch? What does it do when
Speaker 2: it's pushed to the background. But the real red flags
Speaker 2: they often appear around web views.
Speaker 1: Web views okay, so loading web pages inside the app.
Speaker 2: Precisely, we actively hunt for UI WebView delegate or its
Speaker 2: modern equivalents alongside NSR request.
Speaker 1: So finding a UI WebView delegate combined with those request
Speaker 1: classes means the application isn't just operating in a vacuum.
Speaker 1: It has the actual plumbing to render remote web content
Speaker 1: internally or I guess exfiltrate local data out to a
Speaker 1: remote server.
Speaker 2: You nailed it. It confirms a pathway to the Internet.
Speaker 1: Wow. Okay, so just from the headers, we know it
Speaker 1: can talk to the outside world exactly.
Speaker 2: So now we've established the app's internal capabilities. But you know,
Speaker 2: modern iOS applications, even the highly malicious ones, they rarely
Speaker 2: reinvent the wheel. They rely on external frameworks to execute complex.
Speaker 1: Tasks, which brings us to external dependencies. We have to
Speaker 1: map out what the app intends to load into memory
Speaker 1: at runtime. This transitions us to two specific command line utilities,
Speaker 1: right otool and NM.
Speaker 2: Yes, so otool is widely considered the fundamental utility for
Speaker 2: inspecting Apple Maco binaries.
Speaker 1: The Swiss Army knife basically.
Speaker 2: Pretty much it reads the load commands that are embedded
Speaker 2: right in the binary header, and those commands dictate exactly
Speaker 2: how the operating system should map the executable into memory. Okay,
Speaker 2: but the command flag you'll lean on most heavily here
Speaker 2: is O tool.
Speaker 1: Dash L and that's a capital L right, which flags
Speaker 1: the tool to enumerate all the dynamically linked to libraries
Speaker 1: the binary requires to actually function, right, and.
Speaker 2: The output there gives you the exact paths to every
Speaker 2: single shared library. Now, often you'll just see standard system
Speaker 2: paths right, like Apples Foundation or UIKit frameworks.
Speaker 1: Totally normal stuff.
Speaker 2: Yeah, boring stuff. But the critical anomalies you want to
Speaker 2: look for are dynamic paths, specifically ones heavily utilizing the
Speaker 2: at our path.
Speaker 1: Variable at our path the run path search path. That
Speaker 1: is a highly abusable mechanism from what I understand, because
Speaker 1: it tells the dynamic linker to resolve the library path
Speaker 1: relative to where the application is currently running, rather than
Speaker 1: relying on a hard coded absolute system path exactly.
Speaker 2: And malware authors heavily leverage at our paths to sideload
Speaker 2: malicious dynamic libraries.
Speaker 1: Oh wow.
Speaker 2: Yeah. By packaging a compromised dialib within the app's own
Speaker 2: directory structure, they can basically trick the app into loading
Speaker 2: their malicious code instead of a legitimate system library.
Speaker 1: That is an elegant way to obscure the malicious payload
Speaker 1: until the application actually spins up in memory it's hiding
Speaker 1: in plain sight, it really is okay. So, once otol
Speaker 1: has given us that dependency map and showed us where
Speaker 1: it's looking for external code, we shift to analyzing the
Speaker 1: symbols with MM.
Speaker 2: Right, because while otool can dumps symbols, if you use
Speaker 2: specific flags like dash, ODAV and M is explicitly built
Speaker 2: for this. It parses and displays the symbol table of
Speaker 2: a binary.
Speaker 1: And just clarify for everyone. The symbol table contains the
Speaker 1: names and addresses of all the functions and global variables
Speaker 1: the program uses, right, including the ones it expects to find.
Speaker 1: Those dynamic libraries we just mapped out exactly. So if
Speaker 1: O'Toole tells us where the app is looking for external code,
Speaker 1: and M tells us what specific functions it plans to
Speaker 1: call from that code, right.
Speaker 2: You are looking at the unresolved references left behind by
Speaker 2: the developer. It essentially becomes a targeted hunting expedition. At
Speaker 2: that point, you dump the symbols and you filter for
Speaker 2: high risk system calls.
Speaker 1: Give me an example of that. What's a specific symbol
Speaker 1: that spikes your threat radar during static analysis?
Speaker 2: Oh, A prime example is MEMCPI, MENPI Okay, it's a
Speaker 2: standard C library function for moving blocks of memory, but
Speaker 2: it notoriously lacks boundary checking.
Speaker 1: Ah, I see where this is going.
Speaker 2: Right. If we observe a binary aggressively utilizing mengpie, especially
Speaker 2: if it's doing it in close proximity to network socket
Speaker 2: operations or parsing untrusted data, we're very likely looking at
Speaker 2: the foundational mechanics of a buffer overflow exploit.
Speaker 1: Wow. Okay, so that's a huge red flag.
Speaker 2: A massive one. We also actively scan for functions like
Speaker 2: c trace, which malware frequently uses to detect if it's
Speaker 2: being monitored by a debugger.
Speaker 1: Sneaky. Okay. So at this point, the internal blueprints are map,
Speaker 1: the dynamic libraries are enumerated, and the simple tables are parsed.
Speaker 1: We have a lot of data, but so far we're
Speaker 1: just looking at lists of metadata and function pointer, just
Speaker 1: pieces of the puzzle exactly. To understand the actual execution flow,
Speaker 1: like the underlying logic of the malware, we have to
Speaker 1: translate the compiled binary back into something readable. We need
Speaker 1: the X ray machine.
Speaker 2: Yes, we need to pull back the curtain on the
Speaker 2: actual machine code. And this is where disassemblers like Hopper
Speaker 2: or Ida pro become completely indispensable.
Speaker 1: Right.
Speaker 2: They parse the compiled ARM sixty four op codes and
Speaker 2: they translate them back into human readable assembly mnemonics.
Speaker 1: So a disassembler is essentially a universal translator. It takes
Speaker 1: the ones and zeros that only the processor understands and
Speaker 1: reconstructs the logic branches, the register assignments, and memory allocations exactly.
Speaker 2: And translating ARM sixty four architecture is incredibly complex, I mean,
Speaker 2: just due to the sheer volume of registers and the
Speaker 2: intricacies of its branching logic. But a tool like Hopper
Speaker 2: excels at making this approachable for analysts.
Speaker 1: And for those who haven't worked inside a dedicated disassembly environment.
Speaker 1: Hopper provides a really highly visual workspace. It isn't just
Speaker 1: a terminal window of scrolling.
Speaker 2: Texts none of all.
Speaker 1: You get a control flow graph which visually represents the
Speaker 1: code as branching blocks connected by logic pathways. You can
Speaker 1: literally see how an IFL statement splits the execution into
Speaker 1: different memory addresses.
Speaker 2: The visual representation is invaluable, I mean, it saves so
Speaker 2: much time. But honestly, the most powerful feature in Hopper
Speaker 2: for rapid static analysis is the strings window.
Speaker 1: The strings window.
Speaker 2: Yeah, it consolidates all the hard coded plaintext that's embedded
Speaker 2: anywhere in the buying area, which.
Speaker 1: Allows for immediate cross referencing. So if I run a
Speaker 1: search and Hopper for this string HTTP, I don't just
Speaker 1: see the text, right, I can use the cross reference
Speaker 1: feature the XRAS to jump directly to the exact memory
Speaker 1: address where that string is loaded into a register.
Speaker 2: Exactly that workflow. Right there is the core of static analysis.
Speaker 2: You find a suspicious string, you track its cross reference
Speaker 2: to a specific subroutine, and suddenly you are looking at
Speaker 2: the exact logic block responsible for, say xfiltrating data to
Speaker 2: a command and control server.
Speaker 1: That is incredible.
Speaker 2: And if reading raw ARM sixty four assembly proves two
Speaker 2: time consuming, which it offered does. Hopper features a pseudo
Speaker 2: code decompiler with a single click, it attempts to reconstruct
Speaker 2: the assembly back into a C like high level language.
Speaker 1: Which just accelerates the deep code analysis exponentially. Okay, so
Speaker 1: we have covered the conceptual framework. We've got the entire
Speaker 1: command line toolchain down. It's time to move from theory
Speaker 1: to application.
Speaker 2: Let's do it.
Speaker 1: We have an unanalyzed file sitting in our sandbox right now,
Speaker 1: and it is literally labeled malware dot IPA. We are
Speaker 1: going to execute a live zero knowledge takedown of this
Speaker 1: black box. Walk me through it.
Speaker 2: Okay. So the initial protocol for any unknown binary is
Speaker 2: generating a cryptographic hash. We need to check it against
Speaker 2: known threat intelligence databases.
Speaker 1: Okay, So I'm calculating the MD five and SAHA two
Speaker 1: hundred fifty six hashes of the file right now. See
Speaker 1: let's query virus Total and see what the global scanners
Speaker 1: say about this thing. Now, the results are completely negative,
Speaker 1: zero hits across all vendors. Virus Total has never seen it.
Speaker 2: Okay, So we are dealing with a zero day here,
Speaker 2: or at least a highly targeted payload that just hasn't
Speaker 2: been widely distributed yet. Right. Threat intelligence is totally blind here,
Speaker 2: which means we have to rely entirely on our static
Speaker 2: analysis toolchain to figure out what this thing does. So
Speaker 2: let's pry it open.
Speaker 1: Okay. I'm unzipping the dot ipa archive and it reveals
Speaker 1: the standard iOS application bundle structure.
Speaker 2: Right. So, navigating into the payload directory, our first goal
Speaker 2: is to locate the primary MACO executable, but relying on
Speaker 2: the visual filenames in that directory is a really common pitfall.
Speaker 1: Oh why is that?
Speaker 2: Well, the outer wrapper might be named malware or something obvious,
Speaker 2: but the internal binary often utilizes a completely different naming
Speaker 2: convention just to avoid casual detection.
Speaker 1: Uh okay, So to find the definitive entry point, we
Speaker 1: shouldn't just guess. We query the infodot plist file using
Speaker 1: the plutal command, and by reading the cf bundle executable key,
Speaker 1: we bypass any of that directory obfuscation.
Speaker 2: So what does the property list say?
Speaker 1: Okay, looking at it now, it reveals the true executable
Speaker 1: is named no icon no icon. Yeah, no icon.
Speaker 2: Well that immediately implies a conscious effort at stealth.
Speaker 1: Definitely. Okay, we have our target binary. Let's pipe the
Speaker 1: strings command through GRIP and filter specifically for HTTP to
Speaker 1: see if this binary contains hard coded network infrastructure.
Speaker 2: We'll see what it's fit out.
Speaker 1: WHOA, The terminal output is massive. We are looking at
Speaker 1: a really dense list of domains, ip addresses, specific uripaths.
Speaker 2: Wow.
Speaker 1: Yeah, Despite being entirely unknown to the anti virus scanners,
Speaker 1: this application is hardwired to communicate with dozens of external endpoints.
Speaker 2: It's hitting a massive variety of infrastructure, which is very telling.
Speaker 2: This points toward either a domain generation algorithm for command
Speaker 2: and control or it's cycling through a hard coded list
Speaker 2: of drop sites to see what's active.
Speaker 1: Let's dig a little deeper into the broader string stump.
Speaker 1: Then what else is embedded in this binary?
Speaker 2: Okay, Filtering past all those URLs, we uncover some highly
Speaker 2: specific operational plaintext. Look at this, there are distinct references
Speaker 2: to an ad page component at page yeah. And more critically,
Speaker 2: we find strings querying for no icon update and active
Speaker 2: filepath checks looking for other dot IBA packages stored locally
Speaker 2: on the file system.
Speaker 1: Wait, looking for other apps. Let's synthesize those artifacts. We
Speaker 1: have aggressive network requests, references to ap tizing components, and
Speaker 1: mechanisms designed to search for and update secondary IYP of files.
Speaker 1: The primary binary is a stager. It's a dropper. It's
Speaker 1: designed to quietly pull down and install adware or you
Speaker 1: know more destructive secondary payloads in the background.
Speaker 2: Exactly. The behavioral profile strongly aligns with a dropper. But
Speaker 2: and this is key for a dropper to be effective
Speaker 2: on iOS, it has to persist on the device long
Speaker 2: enough to actually execute those secondary downloads.
Speaker 1: Which means it needs to avoid user detection.
Speaker 2: Right, it can't look suspicious.
Speaker 1: Let's check how it masks its presence. Returning to the
Speaker 1: plutal tool, I'll extract the cf bundle display name from
Speaker 1: the infodoup plus what did they name it? The developer
Speaker 1: has set the display name to passbook, masquerading as a
Speaker 1: legacy Apple Wallet component.
Speaker 2: That is incredible calculated.
Speaker 1: It really is, because if a user happens to glance
Speaker 1: at their battery usage or their network settings, seeing Passbook
Speaker 1: consuming resources isn't likely to trigger immediate alarm. It just
Speaker 1: blends right into the expected system noise.
Speaker 2: Yeah, nobody questions pastbook. But the disguise actually goes deeper
Speaker 2: than just the display name. Let's extract the seaf bundle
Speaker 2: identifier from that same property list.
Speaker 1: Okay, pulling that up, the identifier is calm dot wheeling
Speaker 1: dot hidden dot icon dot onian dot launch.
Speaker 2: The developer naming conventions are surprisingly brazen.
Speaker 1: There seriously hidden icon on launch.
Speaker 2: Yeah, but the critical element is the configuration flag attached
Speaker 2: to that bundle identifier. Look at the status flag. It
Speaker 2: is explicitly configured to hidden hidden.
Speaker 1: So wait, by manipulating that specific property list key, the
Speaker 1: application is instructing the iOS springboard demon which is the
Speaker 1: process responsible for managing the home screen UI. Right. Yeah,
Speaker 1: it's instructing it to completely ignore the app's existence.
Speaker 2: That's exactly what it's doing. The icon is literally never
Speaker 2: rendered on the screen.
Speaker 1: Oh my god. It achieves near perfect persistence purely through
Speaker 1: a UI configuration trick.
Speaker 2: Yeah, there is nothing for the user to tack and crucially,
Speaker 2: there's nothing for the user to long press and delete.
Speaker 1: Wow. It operates as an invisible, silent stager. That is
Speaker 1: brilliantly devious. Well, okay, there's one final artifact we need
Speaker 1: to map for this profile. What language was this dropper
Speaker 1: compiled from?
Speaker 2: Good question. So we execute total dash L against the
Speaker 2: no icon binary, and we filtered the dynamic library output
Speaker 2: for any reliance on Swift foundation frameworks.
Speaker 1: Right, looking for that underscore t signature exactly.
Speaker 2: We are checking for that name mangling signature in the
Speaker 2: symbols as well, and the results entirely void. There are
Speaker 2: no Swift dependencies and the classheaders show zero Swift taxonomy.
Speaker 1: So the dropper is written entirely in pure objective C
Speaker 1: completely which structurally that makes a lot of sense. I mean,
Speaker 1: if your goal is to build a stealthy dropper that
Speaker 1: can maximize its compatibility across older, potentially vulnerable iterations of iOS.
Speaker 1: Writing it in objective c ensures it can execute without
Speaker 1: requiring modern runtime environments.
Speaker 2: Exactly you wanted to run on as many devices as possible. Yeah,
Speaker 2: and that takedown right there is a perfect illustration of
Speaker 2: the methodology.
Speaker 1: It really is. We approached an entirely undocumented zero day
Speaker 1: threat and without ever risking execution. We mapped its C
Speaker 1: two infrastructure, identified its true executable, uncovered its stager functionality,
Speaker 1: and analyzed its UI evasion techniques.
Speaker 2: It just proves that a disciplined, structured approach to static
Speaker 2: analysis can force any binary to revealed core architecture.
Speaker 1: He just had to know where to look, absolutely so.
Speaker 1: To synthesize the toolkit for everyone listening, we utilized class
Speaker 1: stump to extract the objective C run time taxonomy and headers.
Speaker 1: We leveraged O tool to map the macho load commands
Speaker 1: and external dynamic libraries, paying special attention to that at
Speaker 1: our path abuse. We employed enronment to parts the symbol
Speaker 1: tables for exploitable C functions. We vitualized the ARM sixty
Speaker 1: four control flow graphs using Hopper, and finally we extracted
Speaker 1: strings and propertyless configurations to completely dismantle a live dropper.
Speaker 2: A very successful mission definitely.
Speaker 1: Now to lock in this methodology, let's run a rapid
Speaker 1: review scenario for you listening pop quiz. If you suspect
Speaker 1: a newly intercepted iOS application is covertly rendering remote web content,
Speaker 1: which command line utility provides the dependency map and what
Speaker 1: specific class header validates that web functionality, Well, you would.
Speaker 2: Run O tool dash L to map the dynamic library dependencies,
Speaker 2: and you would parse the class dump output, specifically hunting
Speaker 2: for the UI WebView delegate.
Speaker 1: Class spot on. Now, the mechanics of our takedown today
Speaker 1: highlight just how effectively malware can weaponize standard configuration files
Speaker 1: like the info dot plist to achieve total invisibility on
Speaker 1: a device.
Speaker 2: It's scary how simple it can be.
Speaker 1: It is, but as we master these manual static analysis techniques,
Speaker 1: we have to acknowledge that the defensive landscape is fundamentally
Speaker 1: shifting beneath us. I mean, we just spent this entire
Speaker 1: session manually tracing op codes, cross referencing strings, and parsing macoheaders.
Speaker 2: Right, taking it step by step.
Speaker 1: But consider the current trajectory of large language models. We
Speaker 1: are rapidly approaching an inflection point where you could just
Speaker 1: feed a fully compiled, highly obfuscated MACO binary directly into
Speaker 1: a specialized AI model. Oh wow, and the AI will
Speaker 1: instantly decompile the ARM sixty four architecture map, the control
Speaker 1: flow graphs, cross reference the network infrastructure, and output a
Speaker 1: comprehensive zero day behavioral analysis in seconds, in seconds, seconds.
Speaker 1: It completely automates the meticulous manual detective work we just covered,
Speaker 1: So it begs the question, as AI effortlessly unravels even
Speaker 1: the most sophisticated compiled binaries, will human reverse engineers be
Speaker 1: rendered obsolete or simply elevated to architects of entirely new
Speaker 1: automated defense paradigms.
Speaker 2: Man it is a profound paradigm shift. The barrier to
Speaker 2: deep technical analysis is dissolving, which means the speed of
Speaker 2: both offense and defense is about to accelerate exponentially.
Speaker 1: It is a transformative horizon to keep your eyes on.
Speaker 1: But until then, master the fundamentals, trust the architecture over
Speaker 1: the interface, and keep diving deep