www.mandiant.com Open in urlscan Pro
2606:4700:300b::a29f:f17d  Public Scan

Submitted URL: https://www.fireeye.com/blog/threat-research/2017/03/introduction_to_reve.html
Effective URL: https://www.mandiant.com/resources/introduction-to-reve
Submission: On December 08 via api from US — Scanned from DE

Form analysis 1 forms found in the DOM

GET /search

<form action="/search" method="get">
  <div class="js-form-item form-item js-form-type-textfield form-item-search js-form-item-search">
    <label class="visually-hidden" for="edit-search">Search</label>
    <input data-drupal-selector="edit-search" type="text" id="edit-search" name="search" value="" size="30" maxlength="128" class="form-text" placeholder="Search">
  </div>
  <div data-drupal-selector="edit-actions" class="form-actions js-form-wrapper form-wrapper" id="edit-actions">
    <button data-drupal-selector="edit-submit-acquia-search" type="submit" id="edit-submit-acquia-search" class="button js-form-submit form-submit">
      <span class="visually-hidden">Submit search form</span>
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 453.7 453.76">
        <defs>
          <clipPath id="prefix__a">
            <path fill="none" d="M0 0h453.7v453.76H0z"></path>
          </clipPath>
        </defs>
        <g clip-path="url(#prefix__a)">
          <path fill="currentColor"
            d="M453.7 416.28L311.81 274.39c49.35-67.5 43.77-162.94-17.15-223.88-67.3-67.35-176.89-67.35-244.19 0s-67.29 176.89 0 244.22a172.45 172.45 0 00223.86 17.15l141.88 141.88zM88 257.25a119.67 119.67 0 11169.23 0 119.87 119.87 0 01-169.23 0">
          </path>
        </g>
      </svg> </button>
  </div>
</form>

Text Content

Skip to main content
 * Advantage Platform
   
   
   MANDIANT ADVANTAGE PLATFORM
   
   PLATFORM OVERVIEW
   
   Automated Defense
   
   Automatically investigate security alerts to reduce false positives.
   
   Security Validation
   
   Validate that security controls are working as expected.
   
   Threat Intelligence
   
   Take decisive action with industry leading threat intelligence.
   
   Attack Surface Management
   
   Fully map your entire environment to mitigate risks.
   
   Managed Defense
   
   Defend your enterprise with managed detection and response.
   
   Close
 * Services
   
   
   MANDIANT SERVICES
   
   ALL SERVICES
   
   Incident Response
   
   Tackle breaches confidently.
   
   Strategic Readiness
   
   Increase resilience to risk.
   
   Technical Assurance
   
   Battle-test how well your security program performs.
   
   Cyber Defense Transformation
   
   Establish and properly orchestrate cyber defenses.
   
   Mandiant Academy
   
   Train your security team to effectively protect your enterprise.
   
   Close
 * Resources
   
   
   RESOURCES
   
   ALL RESOURCES
   
   Customer Stories
   
   See case studies and customer testimonials.
   
   Mandiant Blog
   
   Read expert perspectives and industry news.
   
   Webinars
   
   Expand your cyber security knowledge base.
   
   Podcasts
   
   Listen to our State of the Hack, Eye on Security and Cyber Security
   Effectiveness podcasts.
   
   Reports
   
   Threat Intelligence from front line experts.
   
   Insights
   
   Explore the latest views on key threats, trends and predictions.
   
   Close
 * Company
   
   
   COMPANY
   
   ABOUT MANDIANT
   
   Leadership
   
   Investor Relations
   
   Media Center
   
   Events
   
   Careers
   
   Close


Search
Submit search form
Incident response !
Close
 * Advantage Platform
   * Back
   * Advantage Platform Landing
   * Security Validation
   * Attack Surface Management
   * Managed Defense
 * Services
   * Back
   * Services Landing
   * Incident Response
   * Strategic Readiness
   * Technical Assurance
   * Cyber Defense Transformation
   * Mandiant Academy
 * Resources
   * Back
   * Resources Landing
   * Customer Stories
   * Mandiant Blogs
   * Webinars
   * Podcasts
   * Reports
   * Insights
 * Company
   * Back
   * About Mandiant
   * Leadership
   * Investor Relations
   * Media Center
   * Events
   * Careers


TOP

 * Advantage Login
 * Incident Response Assistance
 * Support

Incident response !


BREADCRUMB

 1. Home
 2. Resources
 3. Introduction to Reverse Engineering Cocoa Applications

Threat Research


INTRODUCTION TO REVERSE ENGINEERING COCOA APPLICATIONS

James T. Bennett
Mar 08, 2017
10 mins read

While not as common as Windows malware, there has been a steady stream of
malware discovered over the years that runs on the OS X operating system, now
rebranded as macOS. February saw three particularly interesting publications on
the topic of macOS malware: a Trojan Cocoa application that sends system
information including keychain data back to the attacker, a macOS version of
APT28’s Xagent malware, and a new Trojan ransomware.

In this blog, the FLARE team would like to introduce two small tools that can
aid in the task of reverse engineering Cocoa applications for macOS. In order to
properly introduce these tools, we will lay a bit of foundation first to
introduce the reader to some Apple-specific topics. Specifically, we will
explain how the Objective-C runtime complicates code analysis in tools such as
IDA Pro, and how to find useful entry points into a Cocoa application’s code
where you can begin analysis.

If you find these topics fascinating or if you want to be better prepared to
investigate macOS malware in your own environment, come join us for a two-day
crash course on this topic that we will be teaching at Black Hat Asia and Black
Hat USA this year.

COCOA APPLICATION ANATOMY

When we use the term “Cocoa application”, we are referring to an application
that is built using the AppKit framework, which belongs to what Apple refers to
as the Cocoa Application Layer. In macOS, applications are distributed in an
application bundle, a directory structure made to appear as a single file
containing executable code and its associated resources, as illustrated in
Figure 1.

Figure 1: Directory structure of iTerm application bundle

These bundles can contain a variety of different files, but all bundles must
contain at least two critical files: Info.plist and an executable file residing
in the MacOS folder. The executable file can be any file with execute
permissions, even a python or shell script, but it is typically a native
executable. Mach-O is the native executable file format for macOS and iOS. The
Info.plist file describes the application bundle, containing critical
information the OS needs in order to properly load it. Plist files can be in one
of three possible formats: XML, JSON, or a proprietary binary format called
bplist. A handy utility named plutil is available in macOS that allows you to
convert between formats, or simply pretty-print a plist file regardless of its
format. The most notable key in the Info.plist file is the CFBundleExecutable
key, which designates the name of the executable in the MacOS folder that will
be executed. Figure 2 shows a snippet of the pretty-printed output from plutil
for the iTerm application’s Info.plist file.

Figure 2: snippet from iTerm application’s Info.plist file

OBJECTIVE-C

Cocoa applications are typically written in Objective-C or Swift. Swift, the
newer of the two languages, has been quickly catching up to Objective-C in
popularity and appears to have overtaken it. Despite this, Objective-C has many
years over Swift, which means the majority of malicious Cocoa applications you
will run into will be written in Objective-C for the time being. Additionally,
older Objective-C APIs tend to be encountered during malware analysis. This can
be due to the age of the malware or for the purpose of backwards compatibility.
Objective-C is a dynamic and reflective programming language and runtime.
Roughly 10 years ago, Objective-C version 2.0 was released, which included major
changes to both the language and the runtime. Where details are concerned, this
blog is referring to version 2.0.

Programs written in Objective-C are transformed into C as part of the
compilation process, making it at least a somewhat comfortable transition for
most reverse engineers. One of the biggest hurdles to such a transition comes in
how methods are called in Objective-C. Objective-C methods are conceptually
similar to C functions; they are a unit of code that performs a specific task,
optionally taking in parameters and returning a value. However, due to the
dynamic nature of Objective-C, methods are not normally called directly.
Instead, a message is sent to the target object. The name of a method is called
a selector, while the actual function that is executed is called an
implementation. The message specifies a reference to the selector that is to be
invoked along with any method parameters. This allows for features like “method
swizzling,” in which an application can change the implementation for a given
selector. The most common way in which messages are sent within Objective-C
applications is the objc_msgSend function. Figure 3 provides a small snippet of
Objective-C code that opens a URL in your browser. Figure 4 shows this same code
represented in C.

Figure 3: Objective-C code snippetFigure 4: Objective-C code represented in C

As you can see, the Objective-C code between the brackets amounts to a call to
objc_msgSend.

Unfortunately, this message sending mechanism causes problems when trying to
follow cross-references for selectors in IDA Pro. While you can easily see all
the cross-references for a given selector from any location where it is
referenced, the implementations themselves are not called or referenced directly
and so there is no easy way to jump from a selector reference to its
implementation or vice-versa. Figure 5 illustrates this problem by showing that
the only cross-reference to an implementation is in the __objc_const section of
the executable, where the runtime stores class member data.

Figure 5: Cross-reference to an implementation

Of course, the information that links these selector references to their
implementations is stored in the executable, and thankfully IDA Pro can to parse
this data for us. In the __objc_const section, a structure identified by IDA Pro
as __objc2_meth has the definition illustrated in Figure 6.

Figure 6: __objc2_meth structure

The first field of this structure is the selector for the method. One of the
cross-references to this field brings us to the __objc_selrefs section of the
executable where you can find the selector reference. Following the
cross-references of the selector reference will reveal to us any locations in
the code where the selector is used. The third field of the structure points to
the implementation of the selector, which is the function we want to analyze.
What is left to do is simply use this data to create the cross-references. The
first of the two tools we are introducing is an IDAPython script named
objc2_xrefs_helper.py that does just that for x86_64 Mach-O executable files
using Objective-C 2.0. This script is similar to older IDAPython scripts
released by Zynamics, however their scripts do not support the x86_64
architecture. Our script is available along with all of our other scripts and
plugins for IDA Pro from our Github repo here. For each Objective-C method that
is defined in the executable, objc2_xrefs_helper.py patches the instructions
that cross-reference its selector to reference the implementing function itself
and creates a cross-reference from the referencing instruction to the
implementation function. Using this script allows us to easily transition from a
selector’s implementation to its references and vice-versa, as shown in Figure 7
and Figure 8.

Figure 7: Cross-references added for implementationFigure 8: View selector’s
implementation from its reference

There is a noteworthy shortcoming to this tool, however. If more than one class
defines a method with the same name, there will only be one selector present in
the executable. For now, the tool ignores these ambiguous selectors.

COCOA APPLICATIONS – WHERE TO BEGIN LOOKING?

Another quandary with reverse engineering Cocoa applications, or any application
built with an application framework, is determining where the framework’s code
ends and the author’s code begins. With programs written in C/C++, the author’s
code would typically begin within the main function of the program. While there
are many exceptions to this rule, this is generally the case. For programs using
the Cocoa Application template in Apple’s IDE, Xcode, the main function simply
performs a tail jump into a function exported by the AppKit framework named
NSApplicationMain, as shown in Figure 9.

Figure 9: A Cocoa application's main function

So where do we look to find the first lines of code written by the application’s
author that would be executed? The answer to that question lies within
NSApplicationMain. In summary, NSApplicationMain performs three important steps:
constructing the NSApplication object, loading the main storyboard or nib file,
and starting the event loop. The NSApplication object plays the important role
of event and notification coordinator for the running application.
NSApplicationMain looks for the name of this class in the NSPrincipalClass key
in the Info.plist file of the application bundle. Xcode simply sets this key to
the NSApplication class, but this class may be subclassed or reimplemented and
the key overwritten. A noteworthy notification that is coordinated by the
NSApplication object is NS‌Application‌Did‌Finish‌Launching‌Notification, which
is designated as the proper time to run any application-specific initialization
code the author may have. To handle this notification, the application may
designate a delegate class that adheres to the NSApplicationDelegate protocol.
In Objective-C, a protocol fills the role traditionally referred to as an
interface in object-oriented parlance. The relevant method in this protocol for
encapsulating initialization code is the application‌Did‌Finish‌Launching
method. By default, Xcode creates this delegate class for you and names it
AppDelegate. It even defines an empty applicationDidFinishLaunching method for
the application developer to modify as desired. With all this information in
hand, the best place to look for the initial code of most Cocoa applications is
in a method named applicationDidFinishLaunching, as shown in Figure 10.

Figure 10: Search for applicationDidFinishLaunching method

If you find nothing useful, then fall back to analyzing the main function. It is
important to note that all this information is specific to apps created using
the Cocoa Application template in Xcode. Cocoa applications do not need to use
NSApplicationMain. One can write their own Cocoa application from scratch,
implementing his or her own version of NSApplicationMain.

INTERFACE BUILDER AND NIB FILES

It was previously mentioned that one of the main responsibilities of
NSApplicationMain is to load the main storyboard or nib file. “Nib” stands for
NeXTSTEP Interface Builder, referring to the Interface Builder application that
is a part of Xcode. Interface Builder allows developers to easily build
graphical user interfaces and even wire their controls to variables and methods
within their code using a graphical interface. As a developer builds GUIs with
Interface Builder, graphs of objects are formed. An object graph is saved in XML
format in a .xib file in the project folder. When the project is built, each
object graph is serialized using the NSKeyedArchiver class and stored in Apple’s
bplist format in a .nib file within the application bundle, typically under the
Resources folder. Xcode writes the name of the main nib file to the
application’s Info.plist file under the key NSMainNibFile. When an application
loads a nib file, this object hierarchy is unpacked into memory and all the
connections between various GUI windows, menus, controls, variables, and methods
are established. This list of connections includes the connection between the
application delegate and the NSApplication class. Storyboards were added to
macOS in Yosemite. They enable the developer to lay out all of the application’s
various views that will be shown to the user and specify their relationships.
Under the hood, a storyboard is a directory containing nib files and an
accompanying Info.plist file. The main storyboard directory is designated under
the key NSMainStoryboardFile in the application’s Info.plist file.

This brings us to the other tool we would like to share, nib_parse.py, which is
available from our Github repo here. nib_parse.py uses ccl_bplist to decode and
deserialize a nib file and print out the list of connections defined within it.
 For each connection, it prints the label for the connection (typically a method
or variable name) and the source and destination objects’ classes. Each object
encoded by NSKeyedArchiver is assigned a unique numeric identifier value that is
included in the output within enclosed parentheses. For appropriate GUI elements
that have textual data associated with them, such as button labels, the text is
included in the script output within enclosed brackets. With this information,
one can determine the relationships between the code and the GUI elements. It is
even possible to rewire the application, changing which functions handle
different GUI events. Note that if a nib is not flattened, it will be
represented as a directory that contains nib files and you can run this tool on
the keyedobjects.nib file located within it instead. For storyboards, you can
run this tool on the various nib files present in the storyboard directory.
Figure 11 shows the output of nib_parse.py when it is used on the MainMenu.nib
file from the recently discovered MacDownloader threat shown in Figure 12. You
may notice that the GUI text in the tool output does not match the GUI text in
the screenshot. In this case, many of the GUI elements are altered at run-time
in the code illustrated in Figure 13.

Figure 11: nib_parse.py output for MacDownloader threatFigure 12:
MacDownloader's initial windowFigure 13: Code updating the text of buttons

The output from nib_parse.py shows that the author used the default delegate
class AppDelegate provided by Xcode. The AppDelegate class has two instance
variables for NSButton objects along with four instance variables for
NSTextField objects. A selector named btnSearchAdware is connected to the same
button with id (49) as the instance variable btnAction. This is likely an
interesting function to begin analysis.

SUMMARY

We hope you have enjoyed this whirlwind tour of reverse engineering Cocoa
applications. If you are interested in getting some more exposure to macOS
internals and analysis tools, reverse engineering and debugging techniques, and
real macOS malware found in the wild, then come hang out with us at Black Hat
this year and learn more!





RELATED THOUGHT LEADERSHIP

Report


IDC MARKETSCAPE: WORLDWIDE INCIDENT READINESS SERVICES 2021 REPORT

 |  2 mins read Blog


ROAD TO SECURITY PREDICTIONS 2022 WITH SANDRA JOYCE, MANDIANT'S EVP, GLOBAL
INTEL & ADVANCED PRACTICES

10.26.2021 Oct 26, 2021  |  2 mins read Blog


FLARE-ON 8 CHALLENGE SOLUTIONS

10.22.2021 Oct 22, 2021  |  2 mins read
your cybersecurity advantage


FOOTER

 * Customers
   * Support
   * Community
 * Partners
   * Mandiant Partners
   * Service Partners
   * Cyber Risk Partners
   * Technology Partners
   * Partner Portal
 * Company
   * About Mandiant
   * Media Center
   * Careers
 * Products and Services
   * Advantage Platform
   * Managed Defense
   * Mandiant Services
   * Mandiant Academy
 * Connect with Mandiant
   * Contact Us
   * Report an Incident
   * Email Preferences

Follow Mandiant
 * 
 * 
 * 
 * 


SOCIAL MENU

© Copyright 2021 Mandiant. All rights reserved.


BOTTOM

 * Privacy & Cookies Policy
 * Terms & Conditions
 * Compliance
 * Site Map

WIR SCHÄTZEN IHRE PRIVATSPHÄRE SEHR
Diese Website nutzt Cookies und verwandte Technologien gemäß der Beschreibung in
unserer Datenschutzrichtlinie zu Zwecken, zu denen unter anderem der Betrieb der
Website, Analyse, verbessertes Nutzererlebnis und Werbung zählen. Sie können
unserer Nutzung dieser Technologien zustimmen oder Ihre eigenen Präferenzen
verwalten.
AUSWAHL VERWALTEN ZUSTIMMEN UND FORTFAHREN ALLE ABLEHNEN
Datenschutzerklärung
Powered by:
Cookie-Präferenzen