在套接字连接时从 kext 验证客户端

Authenticate client from kext upon socket connection

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

理想情况下,我想验证通过 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()),但据我所知,没有可用的加密 KPI,也没有从内核空间 getUDID() 的方法。

是否还有其他关于 "proper" 客户端身份验证的想法?

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

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

Apple 在 AMFI kext (<sys/codesign.h> header) 中具有 implemented 功能,可用于从已签名的二进制文件中获取 TeamID。如果这个 header 将是 public,这正是可以用来验证连接到 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;
}