How to Hack a MacOS Application
Introduction
“How to Hack a MacOS Application”은 Apple의 MacOS에서 동작하는 어플리케이션을 테스팅하는 방법입니다. 전반적인 테스팅 메커니즘과 환경 구성에 대한 내용을 주로 다룹니다.
Directory Structure
Application
Application 디렉토리는 실제 앱 파일과 메니페스트 정보가 위치합니다. MacOS 앱 분석 시 CLI 도구를 통해서 체크하는 부분도 많은데, 이 때 해당 디렉토리의 바이너리를 활용합니다.
/Applications/<APP NAME>/Contents
- Info.plist: 패키지에 대한 자세한 정보
- MacOS: 실제 앱 실행에 사용되는 바이너리가 위치한 디렉토리
- PkgInfo: 패키지 정보
- _CodeSignature: 서명
- Frameworks: 앱에 사용된 프레임워크들
- Resources: 리소스 디렉토리
- CodeResources: 코드 리소스
Data
Data 디렉토리는 앱이 사용하는 데이터들이 모인 디렉토리입니다. 대표적으로 Cache, Local DB 등이 있고 해당 디렉토리도 자세하게 체크해야할 디렉토리입니다.
/Users/<USER NAME>/Library/Application Support/<APP NAME>
Hack Mechanism
File system
위 Directory Structure에서 이야기한 2개의 디렉토리는 정말 중요합니다. 해당 디렉토리에서 분석에 필요한 전반적인 정보를 얻을 수 있습니다.
- /Applications/<APP NAME>/Contents
- /Users/<USER NAME>/Library/Application Support/<APP NAME>
Info.plist
/Applications/<APP NAME>/Contents
에 있는 Info.plist는 앱에 대한 정보를 담고있는 plist(xml) 파일입니다. plist 파일이 떄문에 plutil 등으로 확인해야 정상적인 내용을 볼 수 있습니다.
plutil -p Info.plist
Notion 앱 예시
{
"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
}
버전, 패키지 이름을 비롯하여, CFBundleURLSchemes에서 앱의 스킴 이름, 그리고 개발자가 저장해둔 일부 정보를 보실 수 있습니다.
Strings to Binary
strings 명령은 바이너리 내 문자열을 추출하는 명령입니다. 이를 통해 바이너리에 저장된 문자열을 추출할 수 있습니다.
strings ./MacOS/Notion
때떄로 중요한 API Endpoint나 키 값이 노출되기도 합니다.
API Testing
MacOS Application 또한 Web 기반의 API를 사용할 수 있고 최근에는 Electron app 등 웹을 사용하는 앱의 비중이 높기 떄문에 기존 Web Application 테스팅과 동일하게 보안 테스팅을 진행합니다.
이를 위해선 시스템 프록시 설정으로 MacOS Application에서 발생하는 트래픽이 ZAP이나 Burpsuite 등 Proxy 도구를 거쳐가도록 구성해야합니다. 구성에 대한 자세한 내용은 아래 Environment > Set Proxy 부분을 확인해주세요.
Check Listen Port
Listen Port를 체크하는 것은 간단하지만 중요한 과정입니다. 보통 listen port는 netstat을 생각하지만 lsof 명령으로 PID와 Application 이름을 같이 확인하는 것이 가독성이 좋습니다.
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)
이를 통해 각 App이 Listen 상태로 있는 Port를 확인할 수 있고, 이는 추가적인 테스팅의 좋은 Endpoint가 됩니다.
- HTTP 기반 포트의 경우 웹 기반으로 테스팅할 수 있습니다.
- Socket 기반 포트의 경우 Fuzzing 등으로 오동작을 유도할 수 있습니다.
참고로 이렇게 로컬 포트를 열고 있는 앱은 생각보다 많습니다 🤔
Log Analysis
MacOS Application 또한 iOS App과 동일하게 Console 앱으로 로그를 받을 수 있습니다.
Reverse Engineering
MacOS Application은 최종적으로 바이너리로 컴파일되어 동작하기 때문에 Windows나 Linux Application과 동일하게 Reverse Engineering이 가능합니다. IDA나 Ghidra, Frida를 통해 어플리케이션의 흐름을 분석하고 숨겨진 관리 기능이나 메모리 단 취약점을 찾을 수도 있습니다.
🛠 Environment
Set Proxy
Certificate
Proxy 설정보다 먼저 인증서 설정(RootCA)을 하는 것이 좋습니다. 사용하시는 도구(ZAP or Burp 등) 에서 인증서 파일을 생성하여 다운로드한 후 파일을 더블클릭 하거나 키체인 앱을 통해 인증서 파일을 등록합니다. 이후 해당 인증서는 모두 신뢰 설정 되어야 합니다.
Use System Proxy
시스템 설정
> 네트워크
> 고급
(현재 연결된 네트워크의 상세 설정) > 프록시
> 웹 프록시(HTTP)와 보안 웹 프록시(HTTPS)
에서 시스템 프록시를 설정할 수 있습니다.
Use Proxychains
Proxychains는 시스템 프록시를 중개해주는 도구입니다. 기본값은 Tor network를 사용하도록 되어 있어서 IP 우회 등에 사용되지만, configuation을 통해 지정한 프록시로 통신할 수 있도록 구성이 가능하기 때문에 환경 설정 후 사용 시 매우 편리하게 쓸 수 있습니다.
설치는 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
Configuration 파일은 /usr/local/etc/proxychains.conf
경로에 있습니다. vim으로 열어서 사용할 proxy 포트와 서비스를 지정합니다.
vim /usr/local/etc/proxychains.conf
http 127.0.0.1 8090
이후 proxychains4
명령을 통해 어플리케이션 실행 시 앱이 지정한 Proxy로 통신하게 됩니다.
proxychains4 /Applications/Notion.app/Contents/MacOS/Notion
If use Pulse VPN
회사 등에서 VPN을 위해 Pulse를 사용하느 경우 일반적인 시스템 설정으로 Proxy가 정상적으로 잡히지 않습니다. 이는 Pulse 자체에서도 트래픽을 처리하기 위함이기 때문입니다. 이러한 문제는 Pulse 쪽 Configuration을 조정하여 해결할 수 있고, 이를 쉽게할 수 있는 psproxy란 도구가 있습니다.
먼저 npm을 통해 도구를 설치합니다.
npm i -g psproxy
이후 아래 명령으로 psproxy를 활성화하여 Pulse 사용중에도 트래픽이 우리가 의도한 도구로 흘러갈 수 있도록 변경합니다.
sudo psproxy on
원본 상태로 되돌리기 위해선 아래 명령으로 변경할 수 있습니다.
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