使用Intune审计macOS定位服务的完整指南

本文详细介绍如何使用Microsoft Intune和bash脚本审计macOS设备的定位服务访问,包含三个实用脚本实现定位图标显示控制、应用访问审计和报告生成,帮助企业平衡安全与隐私。

谁在监视?使用Intune审计macOS定位服务

在企业移动安全领域,macOS设备的安全加固是至关重要的一环。本文将重点介绍macOS定位服务的管理,并基于CIS Level 2基准提出两项关键建议。

CIS基准建议

建议2.6.1.2:确保"当系统服务请求您的位置时在控制中心显示定位图标"已启用

当macOS系统服务或应用程序请求位置数据时,必须通过控制中心中的可见图标通知用户。这有助于建立信任,确保用户了解定位跟踪活动,防止任何隐藏进程被忽视。

建议2.6.1.3:审计定位服务访问

许多macOS功能依赖定位服务提供定制信息,从设置时区、显示本地天气到启用"查找我的Mac"。虽然定位服务增加了便利性,但它们也可能带来隐私风险,特别是在政府或医疗保健等敏感环境中。

使用Intune部署脚本

为了简化定位服务设置的管理,我开发了三个可通过Microsoft Intune部署的脚本。

1. 启用定位服务图标

第一个脚本确保当系统服务或应用程序请求您的位置时显示定位服务图标。

脚本概述:

  • 检查相关的plist文件(com.apple.locationmenu.plist)是否存在
  • 如果尚未激活,则启用"显示定位图标"设置
  • 记录所有操作以进行审计
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/bin/bash
# 定义变量
appname="EnableLocationIcon"
logandmetadir="/Library/Logs/Microsoft/IntuneScripts/$appname"
log="$logandmetadir/$appname.log"
plist_path="/Library/Preferences/com.apple.locationmenu.plist"

# 检查日志目录是否已创建
if [ -d "$logandmetadir" ]; then
    echo "$(date) | 日志目录已存在 - $logandmetadir"
else
    echo "$(date) | 创建日志目录 - $logandmetadir"
    mkdir -p $logandmetadir
fi

# 开始记录
exec &> >(tee -a "$log")

# 开始脚本主体
echo ""
echo "##############################################################"
echo "# $(date) | 开始运行脚本 $appname"
echo "##############################################################"
echo ""

# 启用"系统服务显示定位图标"的功能
function enable_location_icon {
    echo "$(date) | 检查 $plist_path 是否存在。"

    if [ -f "$plist_path" ]; then
        echo "$(date) | $plist_path 存在。检查当前设置。"
        current_setting=$(/usr/bin/defaults read "$plist_path" ShowSystemServices 2>/dev/null)

        if [[ "$current_setting" == "1" ]]; then
            echo "$(date) | '显示定位图标'已启用。未进行更改。"
        else
            echo "$(date) | '显示定位图标'已禁用或未设置。现在启用。"
            /usr/bin/defaults write "$plist_path" ShowSystemServices -bool true
            chown root:wheel "$plist_path"
            chmod 644 "$plist_path"

            # 验证更改
            verify_setting=$(/usr/bin/defaults read "$plist_path" ShowSystemServices)
            if [[ "$verify_setting" == "1" ]]; then
                echo "$(date) | 成功启用'显示定位图标'。"
            else
                echo "$(date) | 启用'显示定位图标'失败。请手动检查。"
            fi
        fi
    else
        echo "$(date) | $plist_path 不存在。创建并启用设置。"
        /usr/bin/defaults write "$plist_path" ShowSystemServices -bool true
        chown root:wheel "$plist_path"
        chmod 644 "$plist_path"

        # 验证更改
        verify_setting=$(/usr/bin/defaults read "$plist_path" ShowSystemServices)
        if [[ "$verify_setting" == "1" ]]; then
            echo "$(date) | 成功创建 $plist_path 并启用'显示定位图标'。"
        else
            echo "$(date) | 创建 $plist_path 或启用'显示定位图标'失败。请手动检查。"
        fi
    fi
}

# 执行功能
enable_location_icon

echo "$(date) | 脚本完成。'显示定位图标'设置已应用。"

2. 审计使用定位服务的应用程序

此脚本审计所有访问过定位服务的应用程序,并将它们编译成可读的plist文件。

脚本概述:

  • 将clients.plist从二进制转换为XML以便解析
  • 提取授权使用定位服务的应用程序的bundle ID
  • 将bundle ID解析为应用程序名称并写入plist文件
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
#!/bin/bash
# 定义变量
# 定位服务数据库和临时XML文件的路径
LS_DB="/var/db/locationd/clients.plist"
XML_DB="/tmp/clients.xml"
OUTPUT_FILE="/Library/Preferences/com.company.locationapps.plist"

# 步骤1:检查定位服务数据库是否存在
if [ ! -f "$LS_DB" ]; then
    echo "在 $LS_DB 未找到定位服务数据库"
    exit 1
fi

# 步骤2:将二进制plist转换为XML格式
plutil -convert xml1 -o "$XML_DB" "$LS_DB"

# 步骤3:初始化空数组以存储授权应用程序的名称
authorized_apps=()

# 步骤4:过滤掉非UTF-8字符并解析授权应用程序
while IFS= read -r bundle_id; do
    echo "处理bundle ID: $bundle_id"
    app_path=$(mdfind "kMDItemCFBundleIdentifier == '$bundle_id'" | head -n 1)
    if [ -n "$app_path" ]; then
        app_name=$(mdls -name kMDItemDisplayName -raw "$app_path")
        if [ -z "$app_name" ]; then
            app_name=$(mdls -name kMDItemCFBundleName -raw "$app_path")
        fi
        if [ -z "$app_name" ]; then
            app_name=$(mdls -name kMDItemFSName -raw "$app_path")
        fi

        if [ -n "$app_name" ]; then
            echo "找到应用程序: $app_name ($bundle_id)"
            authorized_apps+=("$app_name ($bundle_id)")
        else
            echo "找到应用程序路径但 $bundle_id 没有显示名称"
            authorized_apps+=("$bundle_id (未找到应用程序显示名称)")
        fi
    else
        echo "未找到 $bundle_id 的应用程序路径"
        authorized_apps+=("$bundle_id (未找到应用程序显示名称)")
    fi

done < <(
    /usr/libexec/PlistBuddy -c "Print" "$XML_DB" | iconv -f UTF-8 -t UTF-8//IGNORE | 
    awk '
        BEGIN { authorized = 0; bundle_id = "" }
        /BundleId =/ { bundle_id = $3 }
        /Authorized = true/ {
            if (bundle_id != "") {
                print bundle_id
                bundle_id = ""
            } else {
                authorized = 1
            }
        }
        /^[^ ]/ {
            if (authorized && bundle_id != "") {
                print bundle_id
                authorized = 0
                bundle_id = ""
            }
        }
    '
)

# 步骤5:调试 - 在创建新文件前检查输出文件是否存在
if ls -l "$OUTPUT_FILE"; then
    echo "DEBUG: 文件对脚本可见。"
else
    echo "DEBUG: 文件对脚本不可见。"
fi

# 步骤6:确保每次运行都重新创建输出文件
if [ -f "$OUTPUT_FILE" ]; then
    echo "找到现有plist。删除它以创建新文件。"
    rm "$OUTPUT_FILE"
else
    echo "文件不存在,将创建: $OUTPUT_FILE"
fi

# 步骤7:创建具有所需结构的新plist
echo "在 $OUTPUT_FILE 创建新的plist文件"
/usr/libexec/PlistBuddy -c "Add :AuthorizedApps array" "$OUTPUT_FILE"

# 步骤8:设置权限以确保未来的检测和访问
chmod 644 "$OUTPUT_FILE"
chown root:wheel "$OUTPUT_FILE"

# 确认权限以验证它们是否正确设置
ls -l "$OUTPUT_FILE"

# 步骤9:使用授权应用程序填充plist
for app in "${authorized_apps[@]}"; do
    echo "添加到plist: $app"
    /usr/libexec/PlistBuddy -c "Add :AuthorizedApps: string $app" "$OUTPUT_FILE"
done

# 步骤10:最终确认消息
echo "定位服务应用程序已写入 $OUTPUT_FILE"

3. 报告使用定位服务的应用程序

最后一个脚本是报告器,这个自定义属性脚本设计用于Intune内的报告目的。

脚本概述:

  • 从com.company.locationapps.plist读取
  • 将授权应用程序列表输出到控制台,以便在Intune中报告
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/bash
# 定义变量

OUTPUT_FILE="/Library/Preferences/com.company.locationapps.plist"

if [ -f "$OUTPUT_FILE" ]; then
    authorized_apps=$(defaults read "$OUTPUT_FILE" AuthorizedApps)
    echo "授权应用程序: $authorized_apps"
else
    echo "未找到使用定位服务的应用程序。"
fi

隐私考虑

虽然审计定位服务访问对于维护安全至关重要,但承认潜在的隐私问题也很重要。列出所有访问位置数据的应用程序可能会无意中暴露有关用户如何与其设备交互的敏感信息。

潜在的隐私风险:

  • 用户担忧:即使用意最好,用户也可能对管理员能够看到哪些应用程序访问其位置感到不安
  • 数据敏感性:在某些环境中,透露特定的应用程序名称可能会无意中披露敏感细节

缓解策略:

  • Intune设备 blade中的可见性:值得注意的是,应用程序在Intune设备 blade中已经可见
  • 匿名化数据:未来的脚本增强可以专注于匿名化这些数据

未来脚本增强

脚本很棒,但总有改进的空间。以下是一些将事情提升到新水平的想法:

  • 匿名报告:修改报告脚本以仅显示使用定位服务的应用程序数量而不是它们的名称
  • 细粒度权限:引入逻辑来区分系统服务和第三方应用程序,提供更细致的报告
  • 自动警报:当新应用程序请求位置访问时通知管理员
  • 计划审计:自动化审计过程以定期运行,确保持续监控而无需管理开销
  • 维护批准应用程序列表,仅对未知/未批准的应用程序发出警报

通过Microsoft Intune部署

分步部署指南:

  1. 将脚本上传到Intune:

    • 在Microsoft Intune中导航到设备 > macOS > 脚本
    • 分别添加前2个脚本,确保它们分配给适当的设备组
    • 导航到设备 > macOS > 自定义属性,上传报告脚本并将其也分配给设备
  2. 监控部署:

    • 使用Intune的报告功能验证脚本是否成功执行
    • 报告脚本将提供关于哪些应用程序正在访问定位服务的反馈
  3. 根据需要调整策略:

    • 根据审计结果,调整应用程序权限或告知用户潜在的隐私影响

结论

管理macOS上的定位服务不仅仅是锁定事物 - 它是在安全性和可用性之间取得平衡。通过定位服务图标显示谁在监视,审计跟踪应用程序行为,您可以完全控制而无需进行全面监视模式。

但请记住,能力越大,责任越大。保持隐私意识,尽可能匿名化,并始终对用户保持透明。采用和沟通可以帮助有效应对这些挑战。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计