2016-02-01 10 views
3

Я создаю kext для дополнительного уровня безопасности на OS X (построенный вокруг KAtuh). Я использую клиент в пользовательском пространстве, который подключается к kext поверх сокетов (по рекомендации Apple) и в основном управляет kext. Поскольку продукт должен обеспечивать дополнительную безопасность для OS X, важно, чтобы он был «как можно более безопасным» от атак. Один вектор атаки следующий: A malicious process impersonates the client and sends malicious control data to the kext, disabling the security mechanism.. Я хочу предотвратить это, выполнив аутентификацию при подключении. Вот мои решения:Аутентификация клиента из kext при подключении сокета

  • Запуск клиента в качестве корня, используйте CTL_FLAG_PRIVILEGED флаг, чтобы обеспечить только корневые клиент может подключаться к 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() из kernelspace.

Есть ли другая идея в том, чтобы делать «правильную» аутентификацию клиентов?

+0

Мне любопытно, как это сделать (и разрешать другие вызовы ядра). Один из вариантов - настроить выделенного непривилегированного пользователя для вашего демона и проверить UUID EUID процесса, пытающегося подключиться. Я не уверен, что это обязательно так, что Apple хочет, чтобы вы это сделали. В любом случае, я добавлю щедрость к этому, как только смогу, и, возможно, напишу запрос DTS, если никто не ответит. – pmdj

+0

@pmdj Возможно, вы знаете способ захватить MAC-адрес из ядра или карты Ethernet или WiFi и использовать его в качестве динамического кода аутентификации? – Joseph

+0

Я не уверен, насколько это безопасно, но вы можете найти экземпляры IOEthernetController и/или IOEthernetInterface всех Ethernet-устройств в системе и запросить их. Я не совсем уверен, как это поможет решить эту проблему, хотя MAC-адреса легко получить. – pmdj

ответ

1

Я просил Apple Support Tech Support ответить на этот вопрос, и они сказали, что единственный поддерживаемый способ ограничить доступ пользователей к kexts - это отличать процессы root и non-root.

Лично в целях уменьшения поверхности атаки было бы действительно полезно отказаться от пользовательских привилегий пользователя. Способ Linux для проверки определенного членства в группе кажется, что он должен работать и с OS X. (Например, вы, как правило, должны быть частью группы «kvm» для использования технологии виртуализации KVM в Linux.) Единственный способ стать членом группы - это получить права root (для настройки группового имени Launch Daemon необходимы привилегии root), поэтому это должно быть безопасным. Я еще должен попробовать это сам, но у меня есть 2 проекта, где это имеет смысл, поэтому я отдам это и обновит этот ответ своими выводами.

+0

Спасибо, что попросили техническую поддержку разработчиков Apple! По крайней мере, теперь мы знаем, что Apple ожидает от нас ... – Joseph

+0

Они сказали, что мы должны подать радары с запросом на повышение. Я постараюсь сделать это в ближайшие 2 недели или около того (рабочая нагрузка сейчас немного сумасшедшая), но чем больше у нас есть запросы, тем больше вероятность того, что она будет добавлена. Если вы сделаете запрос, отправьте свой номер радара, чтобы я мог ссылаться на него. (Я отправлю их, если я доберусь до него.) – pmdj

+0

Я подал это под номером 25165008. – Joseph

0

У Apple есть implemented функциональность в AMFI kext (<sys/codesign.h>), которая может быть использована для получения 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; 
}