【问题标题】:Authenticate client from kext upon socket connection在套接字连接时从 kext 验证客户端
【发布时间】:2016-02-01 13:18:48
【问题描述】:

我正在为 OS X 上的额外安全层构建一个 kext(围绕 KAtuh 构建)。我在用户空间中使用一个通过套接字连接到 kext 的客户端(按照 Apple 的建议),并且基本上控制着 kext。因为该产品应该为 OS X 提供额外的安全性,所以它对攻击“尽可能安全”是很重要的。一种攻击向量如下:A malicious process impersonates the client and sends malicious control data to the kext, disabling the security mechanism.。我想通过在连接时进行身份验证来防止这种情况。以下是我的解决方案:

  • 以root身份运行客户端,使用CTL_FLAG_PRIVILEGED标志确保只有root客户端可以连接到kext。我不确定我是否想让我的客户端以特权模式运行(再次:额外的攻击向量)。

  • 让 kext 只连接到一个客户端。但是,这很容易绕过。

理想情况下,我想验证通过static int ctl_connect(kern_ctl_ref ctl_ref, struct sockaddr_ctl *sac, void **unitinfo) 连接的客户端的身份。我该怎么做?

我也可以在static int ctl_set(kern_ctl_ref ctl_ref, u_int32_t unit, void *unitinfo, int opt, void *data, size_t len) 中进行数据包身份验证,但是,我必须想出一个动态共享密钥。我在考虑secret = SHA256(getUDID()),但AFAIK 没有可用的加密KPI,也没有从内核空间到getUDID() 的方法。

关于对客户端进行“正确”身份验证还有其他想法吗?

【问题讨论】:

  • 我也很好奇这样做(以及授权其他内核调用)的最佳方式。一种选择是为您的守护程序设置一个专用的非特权用户,并检查尝试连接的进程的 EUID 的 UUID。我不确定这一定是苹果希望你这样做的方式。无论如何,我会尽快为此添加赏金,如果没有人回答,我可能会提交 DTS 请求。
  • @pmdj 您是否知道一种从以太网或 WiFi 卡的内核空间获取 MAC 地址并将其用作动态验证码的方法?
  • 我不确定它有多安全,但是您可以找到系统中所有以太网设备的 IOEthernetController 和/或 IOEthernetInterface 实例,并查询它们。我不太确定这将如何帮助解决这个问题,因为 MAC 地址很容易获得。
  • 仅供参考,我已经为此提交了 DTS 请求,因为了解我们的两个项目也会很有用。我怀疑解决方案可能只允许根进程。 :-/
  • 一种可能性是在 kext 加载时为 KAUTH_FILEOP_EXEC 注册一个 KAuth 侦听器并跟踪所有执行的进程;他们的 procname、二进制路径、pid、ppid 等。然后在 ctl_connect 中基于 proc_selfname()proc_selfpid() 以及其他一些公共 KAuth 函数进行一些路径验证。然而问题是 kext 需要在引导链的早期加载。

标签: sockets security authentication kernel-extension xnu


【解决方案1】:

我已经向 Apple 的开发者技术支持询问了这个问题,他们说唯一受支持的限制用户客户端访问 kexts 的方法是区分 root 和非 root 进程。

就个人而言,为了减少攻击面,放弃用户客户端权限确实很有用。检查特定组成员身份的 Linux 方式似乎也适用于 OS X。 (例如,您通常需要成为“kvm”组的成员才能在 Linux 上使用 KVM 虚拟化技术。)成为该组成员的唯一方法是通过 root 权限(设置 Launch Daemon 的 GroupName 需要 root 权限) 所以这应该是安全的。我自己还没有尝试过,但我有 2 个项目可以做到这一点,所以我会试一试,并用我的发现更新这个答案。

【讨论】:

  • 感谢您询问 Apple 的开发技术支持!至少我们现在知道 Apple 期望我们做什么......
  • 他们确实说我们应该提交增强请求雷达。我会在接下来的两周左右尝试这样做(工作量现在有点疯狂)但是我们请求它的人越多,它就越有可能被添加。如果您确实提出请求,请发布您的雷达编号,以便我参考。 (如果我在你之前找到它,我会发布我们的。)
  • 我已在 25165008 下提交此文件。
【解决方案2】:

Apple 在 AMFI kext(<sys/codesign.h> 标头)中具有 implemented 功能,可用于从已签名的二进制文件中获取 TeamID。如果此标头是公开的,那么这正是可用于验证连接到 kext 的客户端进程的内容。

/*
 * Function: csfg_get_teamid
 *
 * Description: This returns a pointer to
 *      the teamid for the fileglob fg
 */
const char *
csfg_get_teamid(struct fileglob *fg)
{
    struct ubc_info *uip;
    const char *str = NULL;
    vnode_t vp;

    if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE)
        return NULL;

    vp = (struct vnode *)fg->fg_data;
    if (vp == NULL)
        return NULL;

    vnode_lock(vp);
    if (!UBCINFOEXISTS(vp))
        goto out;

    uip = vp->v_ubcinfo;
    if (uip == NULL)
        goto out;

    if (uip->cs_blobs == NULL)
        goto out;

    /* It is OK to extract the teamid from the first blob
       because all blobs of a vnode must have the same teamid */    
    str = uip->cs_blobs->csb_teamid;
out:
    vnode_unlock(vp);

    return str;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-08
    • 2021-04-22
    • 2016-03-26
    • 2013-02-14
    • 2012-12-15
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多