hacktricks/macos-hardening/macos-auto-start-locations.md
2023-08-03 19:12:22 +00:00

14 KiB
Raw Blame History

macOS自动启动位置

☁️ HackTricks云 ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

以下是系统中可能导致二进制文件在没有用户交互的情况下执行的位置。

Launchd

launchd是在启动时由OS X内核执行的第一个进程,也是在关机时最后一个完成的进程。它应该始终具有PID 1。此进程将读取和执行在以下位置指定的ASEP plists中的配置:

  • /Library/LaunchAgents:由管理员安装的每个用户代理
  • /Library/LaunchDaemons:由管理员安装的系统级守护程序
  • /System/Library/LaunchAgents由Apple提供的每个用户代理。
  • /System/Library/LaunchDaemons由Apple提供的系统级守护程序。

当用户登录时,位于/Users/$USER/Library/LaunchAgents/Users/$USER/Library/LaunchDemons的plists将以登录用户的权限启动。

代理和守护程序的主要区别在于代理在用户登录时加载,而守护程序在系统启动时加载因为有一些服务如ssh需要在任何用户访问系统之前执行。此外代理可以使用GUI而守护程序需要在后台运行。

<?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>/Users/username/malware</string>
</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>

有些情况下,需要在用户登录之前执行一个代理程序,这被称为PreLoginAgents。例如,这在登录时提供辅助技术时非常有用。它们也可以在/Library/LaunchAgents目录中找到(参见这里的示例)。

{% hint style="info" %}新的守护程序或代理程序配置文件将在下次重启后加载,或使用launchctl load <target.plist>命令加载。也可以使用launchctl -F <file>命令加载没有扩展名的.plist文件但这些.plist文件在重启后不会自动加载。 也可以使用launchctl unload <target.plist>命令卸载(指向它的进程将被终止)。

为了确保没有任何东西(如覆盖)阻止代理程序或守护程序运行,请运行:sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist {% endhint %}

列出当前用户加载的所有代理程序和守护程序:

launchctl list

Cron

使用以下命令列出当前用户的cron作业

crontab -l

您还可以在**/usr/lib/cron/tabs//var/at/tabs/**需要root权限中查看用户的所有cron作业。

在MacOS中可以找到以特定频率执行脚本的几个文件夹:

ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /etc/periodic/

在这里您可以找到常规的cron作业、at作业不常用和周期性作业主要用于清理临时文件。例如可以使用periodic daily来执行每日周期性作业。

周期性脚本(/etc/periodic)是由在/System/Library/LaunchDaemons/com.apple.periodic*中配置的启动守护程序执行的。请注意,如果将脚本存储在/etc/periodic/中以提升特权,它将作为文件的所有者来执行。

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

kext

为了将KEXT安装为启动项它需要被安装在以下位置之一

  • /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

有关内核扩展的更多信息,请查看此部分

登录项

在“系统偏好设置” -> “用户与群组” -> 登录项中,您可以找到用户登录时要执行的项目
可以通过命令行列出、添加和删除它们:

#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"'

这些项目存储在文件 /Users/<username>/Library/Application Support/com.apple.backgroundtaskmanagementagent

At

“At 任务”用于在特定时间安排任务
这些任务与 cron 不同,它们是一次性任务,在执行后会被删除。但是,它们会在系统重启后保留,因此不能排除它们作为潜在威胁的可能性。

默认情况下,它们是禁用的,但是root 用户可以通过以下方式启用它们

sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.atrun.plist

这将在13:37创建一个文件

echo hello > /tmp/hello | at 1337

如果未启用AT任务则创建的任务将不会被执行。

登录/注销挂钩

它们已被弃用,但可以用于在用户登录时执行命令。

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

这个设置存储在 /Users/$USER/Library/Preferences/com.apple.loginwindow.plist 文件中。

defaults read /Users/$USER/Library/Preferences/com.apple.loginwindow.plist
{
LoginHook = "/Users/username/hook.sh";
MiniBuddyLaunch = 0;
TALLogoutReason = "Shut Down";
TALLogoutSavesState = 0;
oneTimeSSMigrationComplete = 1;
}

要删除它:

defaults delete com.apple.loginwindow LoginHook

在前面的例子中,我们创建并删除了一个LoginHook,同样也可以创建一个LogoutHook

root用户的Hook存储在/private/var/root/Library/Preferences/com.apple.loginwindow.plist中。

Emond

苹果引入了一个名为emond的日志记录机制。看起来它从未完全开发,苹果可能已经放弃了它以使用其他机制,但它仍然可用

这个鲜为人知的服务对于Mac管理员来说可能没有太多用处,但对于威胁行为者来说,一个非常好的理由是将其用作持久性机制大多数macOS管理员可能不知道去寻找。检测emond的恶意使用不应该很困难因为该服务的系统LaunchDaemon只会在一个地方寻找要运行的脚本

ls -l /private/var/db/emondClients

{% hint style="danger" %} 由于这个功能很少使用,所以该文件夹中的任何内容都应该是可疑的 {% endhint %}

启动项

{% hint style="danger" %} 此功能已被弃用,因此不应在以下目录中找到任何内容。 {% endhint %}

StartupItem 是一个目录,它被放置在以下两个文件夹之一中:/Library/StartupItems//System/Library/StartupItems/

在这两个位置之一放置一个新的目录后,还需要在该目录中放置两个更多的项目。这两个项目是一个rc脚本和一个包含一些设置的plist。这个plist必须被命名为“StartupParameters.plist”。

{% tabs %} {% tab title="StartupParameters.plist" %}

<?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>

{% tab title="超级服务名称" %}

#!/bin/sh
. /etc/rc.common

StartService(){
touch /tmp/superservicestarted
}

StopService(){
rm /tmp/superservicestarted
}

RestartService(){
echo "Restarting"
}

RunService "$1"

{% endtab %} {% endtabs %}

/etc/rc.common

{% hint style="danger" %} 这在现代 MacOS 版本中不起作用 {% endhint %}

还可以在这里放置在启动时执行的命令。以下是一个常规的 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
}

配置文件

配置文件可以强制用户使用特定的浏览器设置、DNS代理设置或VPN设置。还有许多其他的有效载荷可以被滥用。

您可以运行以下命令来枚举它们:

ls -Rl /Library/Managed\ Preferences/

其他持久化技术和工具

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥