Найти в Дзене
B0rn2beR00T

Решение Injection Attacks (LDAP Injection)

Приветствую! В новой статье разберём атаку LDAP Injection и обойдём аутентификацию web-приложения, используя различные конструкции для изменения запросов в свою пользу. Приступим к разбору кейсов! Облегчённый протокол доступа к каталогам (Lightweight Directory Access Protocol, LDAP) — это протокол, используемый для доступа к серверам каталогов, таким как Active Directory (AD). Веб-приложения могут использовать LDAP для интеграции с AD или другими службами каталогов в целях аутентификации или получения данных. Если пользовательский ввод вставляется в запросы LDAP без надлежащей очистки, могут возникнуть уязвимости, связанные с внедрением кода в LDAP. LDAP-инъекция — это атака, при которой злоумышленник вводит специальные LDAP-операторы в поля ввода приложения, чтобы изменить логику запроса, обойти аутентификацию, получить несанкционированный доступ к данным или модифицировать каталог. Для лучшего понимания как работают инъекции разберём синтаксис LDAP-запросов: Основные операторы LDAP
Оглавление

Приветствую!

В новой статье разберём атаку LDAP Injection и обойдём аутентификацию web-приложения, используя различные конструкции для изменения запросов в свою пользу. Приступим к разбору кейсов!

Немного теории

Облегчённый протокол доступа к каталогам (Lightweight Directory Access Protocol, LDAP) — это протокол, используемый для доступа к серверам каталогов, таким как Active Directory (AD). Веб-приложения могут использовать LDAP для интеграции с AD или другими службами каталогов в целях аутентификации или получения данных. Если пользовательский ввод вставляется в запросы LDAP без надлежащей очистки, могут возникнуть уязвимости, связанные с внедрением кода в LDAP.

LDAP-инъекция — это атака, при которой злоумышленник вводит специальные LDAP-операторы в поля ввода приложения, чтобы изменить логику запроса, обойти аутентификацию, получить несанкционированный доступ к данным или модифицировать каталог.

Для лучшего понимания как работают инъекции разберём синтаксис LDAP-запросов:

Основные операторы LDAP

  • Равенство (=) Пример: (name=Kaylie)
  • Приблизительное равенство (~=) Пример: (name~=Kaylie)
  • Больше/меньше или равно (>=, <=) Пример: (uid>=10) (uid<=10)
  • Любое значение (=*) Пример: (department=*)
  • Любое, но за исключением это значение !(=*) Пример: (!(department=*))

Логические операторы LDAP

  • И (&( )( )) Пример: (&(name=Kaylie)(title=Manager))
  • Или (|( )( )) Пример: (|(name=Kaylie)(title=Manager))
  • Нет (!( )) Пример: (!(name=Kaylie))
And фильтры Or поддерживают более двух аргументов. Например, (&(attr1=a)(attr2=b)(attr3=c)(attr4=d))

Операторы True/False

  • True (&)
  • False (|)

Фильтрация запросов

LDAP поддерживает подстановочный знак «*», поэтому мы можем определять фильтры поиска с подстановочными знаками

  • (name=*) Соответствует всем записям, содержащим атрибут name.
  • (name=K*) Соответствует всем записям, содержащим атрибут name, который начинается с K.
  • (name=*a*) Соответствует всем записям, содержащим атрибут name, в котором есть a.

Атрибуты LDAP

LDAP-атрибуты — это поля/свойства объектов в каталоге (как столбцы в таблице БД). Каждый объект (пользователь, группа, компьютер) имеет набор атрибутов (cn (Common Name), sn (Surname), mail (Основной email), uid (User ID), mobile (Мольный номер) и т.д.). Атрибуты могут быть дефолтными для LDAP и кастомные. Основные можно легко подобрать при наличии уязвимости т.к. они общеизвестны.

LDAP - Обход аутентификации

Сперва нам предоставляют форму авторизации, которая работает через протокол LDAP.

-2

Попробуем зайти под учёткой admin, не зная пароль:

admin:*

-3

Если бы в приложении был пользователь admin, то мы бы зашли т.к. в поле password содержит значение *. То есть, зная синтаксис LDAP-запросов, поиск происходил по всей таблице password пока не нашлось нужное значение пароля. Это говорит о том, что в полях формы авторизации нет фильтрации ввода пользователя и она уязвима к LDAP Injection.

А если пользователь с повышенными правами не с логином admin, а superadmin или administrator или ещё что? По такому же принципу поставим * и перед значением admin и после, если логин содержит это слово где-то в середине. Пароль будет подбираться по такому же принципу, что и раньше.

*admin*:*

-4

А вот и наш флаг! Догадка насчёт логина была верной.

-5

А что если везде внедрить * в двух полях? Принцип будет такой же, как с паролем.

-6

Тогда мы зайдём под первым же найденным пользователем htb-stdnt.

-7

В некоторых случаях веб-приложение может внести звездочку в черный список, что сделает невозможным обход аутентификации с помощью вышеупомянутого метода. К счастью, существует альтернативный метод обхода аутентификации без использования подстановочных знаков.

Например, если мы укажем имя пользователя admin)(|(& и пароль abc), веб-приложение будет использовать следующий поисковый фильтр:

(&(uid=admin)(|(&)(userPassword=abc)))

Всё, что внутри (&(..............), должно быть истинным, чтобы вход был успешным. uid=admin проверяет, что имя пользователя admin. Допустим мы заведомо знаем, что этот логин верный. (|(&)(userPassword=abc)) → это условие OR, внутри которого две части:

  • (&) → это пустой AND, который всегда считается истинным.
  • (userPassword=abc) → проверка пароля, который мы не знаем и следовательно условие ложное.

В OR достаточно, чтобы хотя бы одно условие было истинным, чтобы мы смогли зайти под admin.

Таким образом, нам нужно указать только верное имя пользователя, чтобы войти в указанную учетную запись, тем самым успешно обойдя аутентификацию без использования символа *.

LDAP — кража данных и слепая эксплуатация

В данном случае внедрим другой атрибут description в LDAP-запрос для раскрытия в нём информации:

username=admin)(|(description=a*&password=invalid)

Так запрос LDAP будет выглядеть следующим образом:

(&(cn=admin)(|(description=a*)(userPassword=invalid)))

Для аутентификации нам нужно, чтобы username и password совпали с записями в AD, то есть давали True. Ну, это понятно. Допустим, логин admin мы знаем, однако пароль для нас — загадка.

За счёт оператора OR внедряем атрибут description, где лежит флаг. И будем перебирать значения флага.

-8

Вот, например, если первая буква атрибута будет верной, то сервер отреагирует не "login failed!", а длинной ошибкой сайта:

username=admin)(|(description=h*&password=invalid)

-9

Узнав первое значение флага, двигаем фильтр на позицию вперёд:

username=admin)(|(description=ht*&password=invalid)

Так мы можем перебрать весь флаг в Intruder (флаг содержит только буквы нижнего регистра и спец. символы), а можем написать эксплойт.

Таким образом можно вытаскивать чувствительные данные из различных атрибутов. Такой приём можно также применить без внедрения атрибута. Например, перебрать значения пароля.

Выводы

LDAP-инъекции — это похожая уязвимость на SQL-инъекции, но про неё знают меньше, потому что LDAP используется реже.

Хотя SQL-инъекции известны многим веб-разработчикам, LDAP-инъекции встречаются не так часто. Из-за этого про них мало кто знает. Но если веб-приложение использует LDAP, то такая уязвимость может там быть.

Защититься от LDAP-инъекций просто — нужно экранировать специальные символы, которые могут сломать запрос. Это значит заменять опасные символы на безопасные коды, чтобы они воспринимались как обычный текст, а не как часть команды.

Например, злоумышленник хочет вставить ")(" чтобы сломать запрос, а получает "\29\28" — для LDAP это просто часть текста, а не команда.

Спасибо за внимание! Не забывайте оценивать моё творчество лайком. Всех благ!