KO

EN

How to Hack a MacOS Application

"How to Hack a MacOS Application" describes methods for testing applications that run on Apple's MacOS. It primarily covers the overall testing mechanisms and environment configuration.

Directory Structure

Application

The Application directory contains the actual application files and manifest information. When analyzing MacOS apps, many checks are performed using CLI tools, which leverage the binaries within this directory.

/Applications/<APP NAME>/Contents
  • Info.plist: Detailed information about the package
  • MacOS: Directory where the binaries used to run the app are located
  • PkgInfo: Package information
  • _CodeSignature: Signature
  • Frameworks: Frameworks used by the app
  • Resources: Resources directory
  • CodeResources: Code resources

Data

The Data directory gathers data used by the app. This typically includes Cache and Local DB, and this directory should also be checked carefully.

/Users/<USER NAME>/Library/Application Support/<APP NAME>

Hack Mechanism

File system

The two directories mentioned in the Directory Structure are crucial. You can obtain overall information necessary for analysis from these directories.

  • /Applications/<APP NAME>/Contents
  • /Users/<USER NAME>/Library/Application Support/<APP NAME>

Info.plist

Info.plist located in /Applications/<APP NAME>/Contents is a plist (XML) file containing information about the app. Since it's a plist file, you need to use tools like plutil to view its contents correctly.

plutil -p Info.plist

Notion App Example

{
  "BuildMachineOSBuild" => "19F101"
  "CFBundleDisplayName" => "Notion"
  "CFBundleExecutable" => "Notion"
  "CFBundleIconFile" => "electron.icns"
  "CFBundleIdentifier" => "notion.id"
  "CFBundleInfoDictionaryVersion" => "6.0"
  "CFBundleName" => "Notion"
  "CFBundlePackageType" => "APPL"
  "CFBundleShortVersionString" => "2.0.22"
  "CFBundleURLTypes" => [
    0 => {
      "CFBundleURLName" => "notion"
      "CFBundleURLSchemes" => [
        0 => "notion"
      ]
    }
  ]
  "CFBundleVersion" => "2.0.22"
  "DTCompiler" => "com.apple.compilers.llvm.clang.1_0"
  "DTSDKBuild" => "11.0"
  "DTSDKName" => "macosx11.0"
  "DTXcode" => "1220"
  "DTXcodeBuild" => "12B45b"
  "LSApplicationCategoryType" => "public.app-category.productivity"
  "LSMinimumSystemVersion" => "10.10.0"
  "NSBluetoothAlwaysUsageDescription" => "This app needs access to Bluetooth"
  "NSBluetoothPeripheralUsageDescription" => "This app needs access to Bluetooth"
  "NSCameraUsageDescription" => "This app needs access to the camera"
  "NSHighResolutionCapable" => 1
  "NSMainNibFile" => "MainMenu"
  "NSMicrophoneUsageDescription" => "This app needs access to the microphone"
  "NSPrincipalClass" => "AtomApplication"
  "NSQuitAlwaysKeepsWindows" => 0
  "NSRequiresAquaSystemAppearance" => 0
  "NSSupportsAutomaticGraphicsSwitching" => 1
}

You can find information such as version, package name, the app's scheme name in CFBundleURLSchemes, and some information saved by the developer.

Strings to Binary

The strings command extracts strings from a binary. This allows you to extract strings stored within the binary.

strings ./MacOS/Notion

Sometimes, important API endpoints or key values can be exposed.

API Testing

MacOS Applications can also use web-based APIs, and recently, the proportion of web-based apps like Electron apps has increased. Therefore, security testing is conducted in the same way as traditional Web Application testing.

For this, you need to configure the system proxy so that traffic originating from MacOS Applications passes through proxy tools like ZAP or Burpsuite. For detailed configuration, please refer to the Environment > Set Proxy section below.

Check Listen Port

Checking the listen port is a simple but important process. While netstat is commonly thought of for listen ports, using the lsof command along with PID and Application name provides better readability.

lsof -iTCP -sTCP:LISTEN -n -P

e.g.

lsof -iTCP -sTCP:LISTEN -n -P
COMMAND     PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
rapportd    500 hahwul    5u  IPv4 0xe46fe57c5b35640d      0t0  TCP *:64356 (LISTEN)
rapportd    500 hahwul    6u  IPv6 0xe46fe57c5be4c6ad      0t0  TCP *:64356 (LISTEN)
....
com.docke 33499 hahwul   11u  IPv4 0xe46fe57c5b33f6d5      0t0  TCP 127.0.0.1:62604 (LISTEN)
Notion    96251 hahwul   35u  IPv4 0xe46fe57c5b33c40d      0t0  TCP 127.0.0.1:52981 (LISTEN)

Through this, you can identify the ports on which each app is listening, which serves as a good endpoint for further testing.

  • For HTTP-based ports, web-based testing can be performed.
  • For Socket-based ports, fuzzing can be used to induce malfunctions.

By the way, many apps open local ports like this 🤔

Log Analysis

MacOS Applications, like iOS Apps, can receive logs via the Console app.

Reverse Engineering

MacOS Applications ultimately compile and operate as binaries, allowing for reverse engineering just like Windows or Linux Applications. Through tools like IDA, Ghidra, or Frida, you can analyze the application's flow and potentially find hidden administrative functions or memory-level vulnerabilities.

🛠 Environment

Set Proxy

Certificate

It's recommended to set up the certificate (RootCA) before configuring the proxy. Generate and download the certificate file from your chosen tool (ZAP or Burp, etc.), then double-click the file or use the Keychain Access app to import the certificate. Afterward, this certificate must be trusted.

Use System Proxy

You can set the system proxy in System Settings > Network > Advanced (detailed settings for the currently connected network) > Proxies > Web Proxy (HTTP) and Secure Web Proxy (HTTPS).

Use Proxychains

Proxychains is a tool that mediates system proxies. Its default configuration uses the Tor network for IP obfuscation, but it can be configured to communicate through a specified proxy, making it very convenient to use after setup.

Install it via Homebrew.

brew install proxychains-ng
Usage:	proxychains4 -q -f config_file program_name [arguments]
	-q makes proxychains quiet - this overrides the config setting
	-f allows one to manually specify a configfile to use
	for example : proxychains telnet somehost.com
More help in README file

The configuration file is located at /usr/local/etc/proxychains.conf. Open it with vim and specify the proxy port and service to use.

vim /usr/local/etc/proxychains.conf
http    127.0.0.1       8090

Afterward, when you run an application using the proxychains4 command, the app will communicate through the specified proxy.

proxychains4 /Applications/Notion.app/Contents/MacOS/Notion

If use Pulse VPN

If you are using Pulse VPN for work, etc., the proxy may not be set up correctly with normal system settings. This is because Pulse itself also handles traffic. This issue can be resolved by adjusting the Pulse configuration, and a tool called psproxy can easily do this.

First, install the tool via npm.

npm i -g psproxy

Then, activate psproxy with the following command to ensure traffic flows through your intended tool even when using Pulse.

sudo psproxy on

To revert to the original state, use the following command:

sudo psproxy off

Articles

  • https://www.hahwul.com/2020/09/18/use-proxy-in-macos-and-pulse-with-psproxy-for-zapburp/
  • https://www.hahwul.com/2021/08/28/mac-listen-port/

References

  • none