___           ___           ___           ___           ___           ___     
     /\  \         /\__\         /\  \         /\__\         /\  \         /\  \    
    /::\  \       /:/  /        /::\  \       /:/  /        /::\  \       /::\  \   
   /:/\:\  \     /:/  /        /:/\:\  \     /:/__/        /:/\:\  \     /:/\:\  \  
  /::\~\:\  \   /:/  /  ___   /:/  \:\  \   /::\__\____   /::\~\:\  \   /::\~\:\  \ 
 /:/\:\ \:\__\ /:/__/  /\__\ /:/__/ \:\__\ /:/\:::::\__\ /:/\:\ \:\__\ /:/\:\ \:\__\
 \/_|::\/:/  / \:\  \ /:/  / \:\  \  \/__/ \/_|:|~~|~    \:\~\:\ \/__/ \/_|::\/:/  /
    |:|::/  /   \:\  /:/  /   \:\  \          |:|  |      \:\ \:\__\      |:|::/  / 
    |:|\/__/     \:\/:/  /     \:\  \         |:|  |       \:\ \/__/      |:|\/__/  
    |:|  |        \::/  /       \:\__\        |:|  |        \:\__\        |:|  |    
     \|__|         \/__/         \/__/         \|__|         \/__/         \|__|    
       

Как Работает Kerberos

Оглавление

Общая идея

Kerberos был создан с целью общения множества пользовательстких машин и множества серверов без нужны доверять сети с помощью которой они общаются. Система очень удачная и является основой Active Directory от Microsoft. Общая схема такова что у нас существует один kerberos сервер, который может выдавать тикеты (они же билеты) и с их помощью производится вся аутенфикация всех объектов сети и эти тикеты заменяют пароли. Это круто потому что с украденными тикетами хакер особо ничего сделать не сможет, а вот с паролем сможет много чего и поэтому это куда более безопаснее.
Его модель доверия: все машины сети, и пользовательсткие и серверы доверяют kerberos, это означает что вся сетевая безопасность сосредоточенна на одном только kerberos сервере и его копрометация фактически означает компрометацию сети.

Итак, у нас есть сеть, у нас есть пользовательсткие машины, серверы и kerberos сервер который является KDC (Key Distribution Center). Его тикеты используются для аутенфикации на в сервисах в сети kerberos.

1

Самыми важными вещами в этой системе являются ключи которые представляют собой аналог пароля в Kerberos, тоесть украв его хакер имеет возможность притвориться тем пользователем или сервером чей ключ он украл. Этот ключ является хешом пароля и в идеальной модели его (ключ) не знает никто кроме владельца ключа и KDC. Последний же сохраняет все ключи с именами их владельцев в своей собственной таблице и понимает, какой ключ кому принадлежит.

Сервисы KDC

У KDC есть 3 сервиса: kpasswd, kerberos и TGS. Сейчас поговорим о двух последних. Фактически, они выполняют схожие функции с некоторыми отличиями, они оба выдают тикеты для сервисов но такое разделение нужно для того, чтобы пользователь не вводил свой пароль каждый раз когда аутенфицируется и хочет “поговорить” с сервисом, потому что это небезопасно и раздражает пользователя. Протокол kerberos нужен для того чтобы получить тикет для сервиса TGS, который уже будет выдавать больше билетов для сервисов с которыми ты хочешь взаимодействовать. Так же 2 протокола здесь для бОльшей безопасности, сервис kerberos требует ключ пользователя для того чтобы дать выдать тикет для сервисов, в отличие от TGS, что не слишком безопасно потому что в таком случае ключ будет постоянно нужен и его можно будет украсть из памяти рабочей машины. Поэтому после получения тикета для TGS сервиса, который будет давать нам больше билетов, так как он не требует ключа пользователя для выдачи билетов то и сам ключ можно удалять после того как был получен тикет для TGS сервиса.

Так же нужно быть осторожным с повторным использованием имён в kerberos, дело в том что имя это лишь строка в таблице и новый “Боб” может иметь права как старый “Боб”, и поэтому тут нужно быть осторожным.

Структура тикета

Итак, сам первый тикет для будущего использования сервиса TGS представляет из себя общий тикет клиента и сервера (Tc,s) - его структура:

Tc,s(имя_клиента,имя_сервера,ip,метка времени, время жизни, ключ_клиента, ключ_сервера)Ks

Где Ks - это ключ сервера которым зашифрован тикет.

В данном случае это запрос на тикет для сервиса TGS и он является сервером в этой конструкции.

Когда пользователь хочет поговорить с TGS то он дает об этом знать kerberos. Пользователь даёт лишь своё имя и имя сервиса, в ответ получает зашифрованный ключом клиента тикет для общения между пользователем и сервисом. В ответе сервиса kerberos содержится общий ключ для пользователя/сервиса, который будет использоваться обеими сторонами, и защифрованный ключом сервиса, к которому хочет обратиться пользователь, обший тикет для пользователя/сервиса. Тоесть, вот такая структура:

((Tc,s)Ks; Kc,s)Kc; где Tc,s - тикет клиента и сервера; Kc,s - общий ключ шифрования; Ks - ключ сервера; Kc - ключ клиента.

2

Преимущество безопасности тикетов

Тикет Tс,s шифруется ключом сервера для того чтобы единственное что может сделать тот, кто получает тикет (а это может сделать любой до версии 5) это отдать тикет серверу с которым ты хочешь поговорить. В 5-ой версии керберос стал принимать такие запросы только с хешем метки времени и ключа клиента H{timestamp,Kc} из-за возможности офлайн брутфорса тикета который отправлен как респонс. Тaк же в 5-ой версии перестали использоваться общие ключи шифрования в угоду отдельным для пользователя и сервиса, тоесть вместо одного общего ключа в тикете стали содержаться 2 раздельных ключа.

Тикет для TGS сервиса который с которым ты можешь получать билеты у TGS сервиса, временный, и хакер сможет работать от имени пользователя только пока тикет “жив” и после некоторого времени он будет уже не действителен, в отличии от ключа юзера который меняется только при смене пароля пользователя, что не часто.

Обычно, такая модель используется для доступа к TGS сервису, дабы он мог давать тебе больше билетов позже. И, как я уже упомянул, крутая вещь в этом всём заключается в удалении из памяти ключа клиента после того как он взял билет для TGS сервиса при инициализации машины, тоесть после билета к TGS ключ нам нужен будет только когда потребуется создать новый билет к TGS. И если хакер украдет этот тикет то сможет работать от имени пользователя только пока тикет “жив” и после некоторого времени он будет уже не действителен, в отличии от ключа юзера который меняется только при смене пароля пользователя, что не часто. Но пользователь будет держать у себя в памяти общий ключ клиента и TGS (Kc,s). Возникает вопрос, а чем это лучше чем оставлять Kc? Один способ спотреть на это: хакер не сможет использовать его вне соединения для которого этот общий ключ создавался.

Так же для этого ему нужны вот эти данные из респонса kerberos (Tc,s)Ks для общения с сервисом, в данном случае с TGS. Если кто-то просто возьмёт и укадет компьютер, всё что он получит это билет для TGS, что является меньшим зло чем пароль, так как даёт доступ только на некоторое время.

Работа с сервисом TGS

Теперь, когда у нас есть тикет для общения с TGS, мы можем просить у него билеты. Общение с ним происходит так, мы (пользователь) посылаем ему: Имя сервера с которым хотим говорить и тикет (Tk,c)Ks который мы получили от kerbеros. На все эти данные TGS отвечает почти тем же самым чем отвечал kerberos в самом начале, а именно

((Tk,c)Ks; Kc,s)Kc,tgs

3

Единственное отличие здесь, это то что теперь весь респонс зашифрован совместным ключом между клиентом и TGS, так как ключ клиента мы больше не используем. Еще раз вернусь к тому что в версии 5 при установлении соединения используется 2 ключа, один для сообщений от клиента к серверу, другой от сервера к клиенту. Такой подход защищает от атак повторного использования (replay) при котором некоторый ответ сервера можно использовать как запрос клиента при том что ключ для них общий.

Нюансы безопасности

Теперь представим ситуацию: мы, как клиент, желаем получить доступ к серверу по ssh с именем клиента “Боб”, и мы не в kerberos системе, тогда мы посылаем наш пароль напрямую к серверу. И что делает сервер? Он идёт к KDC серверу и просит билет для пользователя “Боб” который сервер посылает и зашифровывает паролем Боба. Уязвимость в том, что мы можем сыграть роль KDC и послать респонс для ssh машины который дойдет до неё раньше чем респонс от настоящего kerberos сервера. Иными словами мы можем залогиниться под любым существующим именем пользователя, послать любой пароль в ssh, послать ответ якобы от KDC который будет зашифрован паролем который мы послали в ssh и ssh сервер позволит нам войти. Защита от этого такая: ssh сервер прежде чем запросить для нас тикет, спрашивает у TGS тикет для разговора с тем же самым ssh сервером, то есть с самим собой. И если ssh сервер может корректно расшифровать респонс, тогда она знает что KDC сервер легимитивный, потому что он знает его ключ.

kpasswd

А что случится, если мы захотим поменять наш пароль? В таком случае нам поможет сервис kpasswd. Он принимает на вход только тикет который пользователь получает от сервиса kerberos для использования сервиса kpasswd и меняет пароль пользователя. Тикеты от сервиса kerberos имеют один бит который показывает что этот билет от kerberos и только такие билеты принимает kpasswd так как только сервис kerberos требует ключ клиента который в общей системе kerberos заменяет пароль. Потому что иначе хакер может использовать билеты от TGS которые он мог украсть и которые не требуют напрямую ключа пользователя.

Еще существует проблема того что хакер может сохранять пакеты смены пароля которые пользователь посылал к kpasswd и которые зашифрованны ключом клиента. Всё это он делал на протяжении длительного периода времени. Таким образом если однажды каким либо образом хакер узнает старый пароль пользователя, который особо им не дорожит, он ведь старый и он давно сменил его. Тогда хакер сможет получить старый ключ пользователя и расшифровать реквест смены пароля который когда то давно пользователь слал сервису kpasswd, и получить новый пароль. В 5-ой версии kerberos в протоколе kpasswd используется еще и алгоритм диффи-хелмана который добавляет дополнительное секретное значение для общения клиента и сервера.

Заключение

Вот и общие принципы работы Kerberos, на деле всё не так сложно и в общей картине очень безопасно но такие вещи как replay атаки или подделка ответа KDC напоминают что дьявол в мелочах.