
macOS ऐप बंडलों, plist फ़ाइलों और launchd प्रोसेस व्यवहार पर शैक्षिक गहन अध्ययन, साथ ही पेलोड को .app फ़ाइलों के रूप में पैकेज करने और प्रोसेस-ट्री मॉनिटरिंग से बचने पर आक्रामक सुरक्षा नोट्स।
Linux से या Windows से macOS पर आना एक अनजान नई दुनिया में चलने जैसा महसूस हो सकता है। चूँकि Linux open-source है और Windows अच्छी तरह से documented और बहुत लोकप्रिय है (और macOS वास्तव में इन दोनों में से नहीं है), macOS कभी-कभी चुनौतीपूर्ण हो सकता है। इस blogpost में, मैं macOS पर आपके सामने आने वाली कुछ पहली चीज़ों पर चर्चा करने का इरादा रखता हूँ - Apps, हर जगह Apps!
Windows या Linux पृष्ठभूमि से आने पर, Apps की अवधारणा अजीब लग सकती है। हम सभी जानते हैं कि threads "निष्पादन की इकाइयाँ" हैं और processes अपने स्वयं के address space वाले threads के कंटेनर हैं -- इसमें और क्या है? खैर, processes शायद ही कभी एकल फ़ाइलों में deployed होते हैं। Windows और Linux दोनों पर कोड को कार्य करने के लिए कई चीज़ों की आवश्यकता हो सकती है, उनमें से कुछ हैं:
.dll, .so)। उदाहरण के लिए, C runtime library (msvcr<version>.dll Windows पर, libc-<version>.so) साथ ही अन्य निर्भरताएँ।PE नामक प्रारूप में आती हैं, जिसमें निर्देशिकाएँ होती हैं - उनमें से एक resource directory है (यहाँ कुछ हद तक documented भी है) जिसमें संसाधन हो सकते हैं (images, strings और अन्य)। संसाधनों को निश्चित रूप से डिस्क से dynamically भी लोड किया जा सकता है।PE फ़ाइल में मौजूद हो सकते हैं (यहाँ पढ़ें) या catalogue फ़ाइलों में (अर्थात् बाह्य रूप से)।xml, ini, json) और Windows Registry के बीच विभाजित होती हैं।खैर, macOS Application Bundles पर बहुत जोर देता है। विचार यह है कि प्रोग्राम को चलाने के लिए आवश्यक (लगभग) सब कुछ एक निर्देशिका संरचना में पैकेज किया जाए - इसमें संसाधन, localization जानकारी आदि शामिल हैं। बेशक, सब कुछ अच्छी तरह से पैकेज नहीं किया जा सकता (उदाहरण के लिए, C runtime library) - लेकिन इसका मतलब यह है कि चीज़ें एक साथ bundled होती हैं - विशाल Registry को नेविगेट करने या अस्पष्ट configuration फ़ाइल स्थानों के लिए manual pages पढ़ने की कोई आवश्यकता नहीं है। Application bundles केवल .app से समाप्त होने वाली निर्देशिकाएँ हैं - भले ही UI .app extension (और यह तथ्य कि यह एक निर्देशिका है) छिपा देता है।
एक attacker के दृष्टिकोण से यह दिलचस्प है - चूँकि एक Application Bundle में मनमाने icons हो सकते हैं और यह .app extension छिपाता है - अनजान उपयोगकर्ता को ऐसे ऐप पर क्लिक करने के लिए धोखा देकर malware वितरित किया जा सकता है। उदाहरण के लिए, PDF icon वाली Resume.app फ़ाइल के बारे में सोचें।
Application Bundle की निर्देशिका संरचना को आसानी से देखा जा सकता है, जाहिर है अंतर्निहित Calculator App द्वारा:
jbo@McJbo ~ % cd /System/Applications/Calculator.app
jbo@McJbo Calculator.app % ll
total 0
drwxr-xr-x 3 root wheel 96 Mar 17 21:34 .
drwxr-xr-x 43 root wheel 1376 Mar 17 21:34 ..
drwxr-xr-x 9 root wheel 288 Mar 17 21:34 Contents
jbo@McJbo Calculator.app % cd Contents
jbo@McJbo Contents % ll
total 16
drwxr-xr-x 9 root wheel 288 Mar 17 21:34 .
drwxr-xr-x 3 root wheel 96 Mar 17 21:34 ..
-rw-r--r-- 1 root wheel 2147 Mar 17 21:34 Info.plist
drwxr-xr-x 3 root wheel 96 Mar 17 21:34 MacOS
-rw-r--r-- 204 root wheel 8 Mar 17 21:34 PkgInfo
drwxr-xr-x 4 root wheel 128 Mar 17 21:34 PlugIns
drwxr-xr-x 54 root wheel 1728 Mar 17 21:34 Resources
drwxr-xr-x 3 root wheel 96 Mar 17 21:34 _CodeSignature
-rw-r--r-- 1 root wheel 461 Mar 17 21:34 version.plist
jbo@McJbo Contents % cd MacOS
jbo@McJbo MacOS % ll
total 344
drwxr-xr-x 3 root wheel 96 Mar 17 21:34 .
drwxr-xr-x 9 root wheel 288 Mar 17 21:34 ..
-rwxr-xr-x 1 root wheel 540912 Mar 17 21:34 Calculator
jbo@McJbo MacOS %
जैसा कि आप देख सकते हैं, Calculator.app एक निर्देशिका है। इसके अंतर्गत एक ही item है - Contents नामक एक और निर्देशिका।
Contents के अंतर्गत कई items हैं:
Info.plist - App के बारे में metadata रखता है। इस पर बाद में और चर्चा करेंगे।MacOS - App का मुख्य executable रखता है (जैसा कि तीसरी निर्देशिका listing में देखा जा सकता है)।PkgInfo - अनिवार्य नहीं। एक binary फ़ाइल जो पैकेज जानकारी रखती है।PlugIns - अनिवार्य नहीं। एक निर्देशिका जिसमें App के लिए plugins हो सकते हैं। Calculator के पास दो हैं - एक "Basic and Scientific" के लिए और एक "Hexadecimal" के लिए (मैं वास्तव में नहीं जानता कि उन्होंने यह अलगाव क्यों किया, और मुझे परवाह भी नहीं है)।Resources - अनिवार्य नहीं। जैसा कि नाम से पता चलता है, संसाधन रखता है। वहाँ आपको कई items मिल सकते हैं, जिनमें Icons के साथ .icns फ़ाइल, साथ ही localization से संबंधित .lprroj suffix वाली निर्देशिकाएँ शामिल हैं।_CodeSignature - अनिवार्य नहीं। जैसा कि नाम से पता चलता है - कोड signing जानकारी रखता है।version.plist - अनिवार्य नहीं, संस्करण जानकारी रखता है।ध्यान दें कि बहुत कम items आधिकारिक रूप से आवश्यक हैं। वास्तव में, हम बिना कुछ compile किए भी अपना पहला App बना सकते हैं!
लेकिन पहले हमें उस Info.plist फ़ाइल पर चर्चा करनी होगी।
आप macOS को जितना अधिक देखेंगे, उतनी ही अधिक ये अजीब फ़ाइलें मिलेंगी। ये केवल बेहतर रूप में प्रस्तुत configuration फ़ाइलें हैं।
उनके पास हमेशा .plist extension होगा, जो उनके औपचारिक नाम: Property list files को बुलाने का एक छोटा तरीका है।
दुर्भाग्य से, Apple द्वारा 3 अलग-अलग plist प्रारूप बनाए रखे जाते हैं:
xml प्रारूप, जो मनुष्यों द्वारा पठनीय है।json प्रारूप, जो व्यापक रूप से उपयोग नहीं किया जाता।bplist टेक्स्ट द्वारा दिखाई देता है।सौभाग्य से, plutil नामक एक utility है जो सभी प्रारूपों का समर्थन करती है। किसी plist फ़ाइल को output करने के लिए, बस plutil -p का उपयोग करें। उदाहरण के लिए:
jbo@McJbo Contents % plutil -p Info.plist | head -n 20
{
"BuildMachineOSBuild" => "22A380007"
"CFBundleDevelopmentRegion" => "English"
"CFBundleExecutable" => "Calculator"
"CFBundleGetInfoString" => "10.14, Copyright © 2000-2018, Apple Inc."
"CFBundleHelpBookFolder" => "Calculator.help"
"CFBundleHelpBookName" => "com.apple.Calculator.help"
"CFBundleIconFile" => "AppIcon"
"CFBundleIconName" => "AppIcon"
"CFBundleIdentifier" => "com.apple.calculator"
"CFBundleInfoDictionaryVersion" => "6.0"
"CFBundleName" => "Calculator"
"CFBundlePackageType" => "APPL"
"CFBundleShortVersionString" => "10.16"
"CFBundleSignature" => "????"
"CFBundleSupportedPlatforms" => [
0 => "MacOSX"
]
"CFBundleVersion" => "223"
"CTIgnoreUserFonts" => 1
jbo@McJbo Contents %
plutil में conversion कार्यक्षमताएँ भी built-in हैं - हम अभी उन्हें प्रदर्शित नहीं करेंगे।
Apple किसी App के Info.plist में कई आवश्यकताओं का documentation करता है, लेकिन वास्तव में बहुत कम फ़ील्ड अनिवार्य हैं। यहाँ कुछ दिलचस्प फ़ील्ड हैं:
CFBundleExecutable - मुख्य executable का नाम, जो MacOS निर्देशिका के अंतर्गत होने की उम्मीद है।CFBundleIconFile - icon फ़ाइल का नाम। अनिवार्य नहीं।CFBundleIdentifier - App Bundle के लिए एक पहचानकर्ता। Apple reverse DNS notation (जैसे com.apple.calculator) का उपयोग करने की सलाह देता है।CFBundleName - bundle का नाम।इसे ध्यान में रखते हुए, हम अपना पहला शानदार ऐप बना सकते हैं, बिना कोडिंग किए भी! एक नज़र डालें:
#!/bin/zsh
# Create Bundle structure
mkdir -p ./MyApp.app/Contents/MacOS
# Create main executable file - a shell script in our case
cat <<EOF > ./MyApp.app/Contents/MacOS/MyApp
#!/bin/zsh
osascript -e 'tell app "Finder" to display dialog "Hello from MyApp!"'
EOF
chmod +x ./MyApp.app/Contents/MacOS/MyApp
# Create the Info.plist file
cat <<EOF > ./MyApp.app/Contents/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>MyApp</string>
<key>CFBundleIdentifier</key>
<string>com.myapp</string>
<key>CFBundleName</key>
<string>MyApp</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
</dict>
</plist>
EOF
यह MyApp नामक एक नया ऐप बनाएगा - इसे क्लिक करने पर बस zsh script (जिसे MyApp कहा जाता है) चलेगी।
ध्यान दें कि यह osascript का उपयोग करता है, जो एक AppleScript दुभाषिया है और मुसीबतों का पिटारा है, लेकिन यह केवल एक डायलॉग दिखाएगा जिसमें Hello from MyApp! लिखा होगा। आप उस zsh shell फ़ाइल में स्पष्ट रूप से मनमाना कोड लिख सकते हैं। नए macOS संस्करणों में zsh को osascript को कॉल करने की अनुमति माँगने वाला एक prompt दिखाई दे सकता है - हम भविष्य के post में चर्चा करेंगे कि ऐसा क्यों होता है, लेकिन ध्यान दें कि पहली अनुमति के बाद यह नहीं पूछेगा।
किसी App को लॉन्च करने का मतलब है कि एक process अभी भी बनाया जाता है - जाहिर है वह जो CFBundleExecutable द्वारा इंगित किया गया है। यह किस process के अंतर्गत चलता है? आइए देखें:
jbo@McJbo ~ % open -a Calculator
jbo@McJbo ~ % ps -A -j | grep Calculator | grep -v grep
jbo 12067 1 12067 0 1 S ?? 0:00.41 /System/Applications/Calculator.app/Contents/MacOS/Calculator
jbo@McJbo ~ %
open कमांड Calculator App पर डबल-क्लिक करने के बराबर है - यह काफी आकर्षक है और हम इस पर जल्द ही चर्चा करेंगे।
अब जब Calculator चल रहा है, हम चल रहे processes को दिखाने के लिए ps का उपयोग करते हैं। जैसा कि अपेक्षित था, /System/Applications/Calculator.app/Contents/MacOS/Calculator वह process है जो चलता है और इसका PID 12067 है। हालाँकि, इसका parent process ID 1 है!
Process ID 1 macOS में /sbin/launchd है। यह "system wide और per-user daemon/agent manager" है। आप इसे services.exe (यदि आप Windows पृष्ठभूमि से आते हैं) या systemd (यदि आप Linux से परिचित हैं) के रूप में कल्पना कर सकते हैं। सेवाओं (जिन्हें macOS पर Launch Agents और Launch Daemons कहा जाता है) के प्रबंधन के अलावा, यह सभी Applications का parent भी है, जो उन कारणों में से एक है जिनकी वजह से macOS पर एक सार्थक process tree प्राप्त करना चुनौतीपूर्ण है।
दिलचस्प बात यह है कि आप /System/Applications/Calculator.app/Contents/MacOS/Calculator को सीधे invoke करके Calculator App को केवल एक process के रूप में चला सकते हैं, लेकिन यह launchd की child नहीं होगा:
jbo@McJbo ~ % /System/Applications/Calculator.app/Contents/MacOS/Calculator &
[1] 12502
jbo@McJbo ~ % 2023-04-04 15:54:22.987 Calculator[12502:1297087] XType: XTFontStaticRegistry is enabled by Info.plist.
jbo@McJbo ~ % ps -A -j | grep Calculator | grep -v grep
jbo 12502 951 12502 0 1 SN s000 0:00.31 /System/Applications/Calculator.app/Contents/MacOS/Calculator
jbo@McJbo ~ % echo $$
951
jbo@McJbo ~ %
वास्तव में, Calculator सुचारू रूप से चलता है, लेकिन अब यह हमारे terminal की child process है।
जिस व्यवहार को हमने देखा है उसमें एक बात ध्यान देने योग्य है कि attackers इसका उपयोग विभिन्न उद्देश्यों के लिए कर सकते हैं। उदाहरण के लिए, attackers सुरक्षा उपकरणों से बचने के लिए process tree से आसानी से बाहर निकल सकते हैं, साथ ही logic vulnerabilities का दुरुपयोग भी कर सकते हैं (यदि आपके पास समय हो तो मेरा macOS Sandbox escape vulnerability writeup पढ़ें)।
launchd की कुछ अन्य दिलचस्प ज़िम्मेदारियाँ भी हैं (LaunchAgents and LaunchDaemons के बारे में पढ़ें) लेकिन हम अभी उन पर चर्चा नहीं करेंगे।
यहाँ मैंने आपको एक प्रकार का bundle दिखाया है लेकिन और भी बहुत कुछ हैं (यह पूरी सूची नहीं है):
.app - हमने इसे देखा है, ये Application Bundles हैं जो Apps के कंटेनर हैं।.framework - Frameworks रखता है, जो लोड करने योग्य bundles हैं। हाँ, macOS में आप किसी loadable फ़ाइल (.dylib) पर dlopen कॉल कर सकते हैं या पूरे framework bundle (संसाधनों, कोड आदि के साथ) को लोड कर सकते हैं।.kext - kernel extensions रखता है, जो loadable bundles हैं लेकिन macOS kernel के लिए। हाल के OS संस्करणों में Apple वास्तव में kernel extensions की संख्या कम करने की पूरी कोशिश करता है।.plugin - जैसा कि नाम से पता चलता है, plugins के लिए एक कंटेनर।यह छोटे blogposts की एक श्रृंखला का पहला भाग है जिसका उद्देश्य लोगों को macOS research की ओर संक्रमण में मदद करना है।
मैंने offensive security दृष्टिकोण से सबसे पहले यह देखा कि payloads को एक सुंदर app संरचना में पैकेज करना कितना आसान है।
हालाँकि चीज़ें इतनी सरल नहीं हैं - अगले कुछ blogposts में हम जानेंगे कि macOS की कई सुरक्षा विशेषताओं के कारण code execution प्राप्त करना उतना आसान नहीं है।
जुड़े रहें!
Jonathan Bar Or (https://jonathanbaror.com)