FreeIPA Pentesting

This info was taken from the posts:

Basic Information

It is an open source alternative to Microsoft Windows Active Directory, primarily used as an integrated management solution for Unix environments. Similar to Active Directory, FreeIPA implements a full LDAP directory infrastructure backed by an MIT Kerberos Key Distribution Center. It uses the Dogtag Certificate System for CA & RA certificate management, giving it the ability to handle multi-factor authentication, including smartcards. SSSD is used to integrate FreeIPA into the standard Unix authentication process.


Files & Env Vars

  • /etc/krb5.conf: The krb5.conf file contains the Kerberos client information required to be enrolled in the domain. This includes the locations of KDCs and admin servers for the Kerberos realms of interest, defaults for the current realm and for Kerberos applications, and mappings of hostnames onto Kerberos realms.
  • /etc/ipa/default.conf: This is the default configuration file for IPA servers, it is used to set system-wide defaults to be applied when running IPA clients and servers.
  • /etc/krb5.keytab: The krb5.keytab file is required on all hosts inside of the domain. It is required as part of the authentication process to the KDC.
  • KRB5CCNAME: If set, this variable points to the location of the CCACHE Ticket to be used for authentication.
  • KRB5_KTNAME: If set, this variable points to the location of the Keytab file to be used for authentication.
  • KRB5_CONFIG: If set, this variable points to the location of the Kerberos configuration file.
  • KRB5_KDC_PROFILE: If set, this variable points to the location of the KDC configuration file, which contains additional configuration directives for the Key Distribution Center daemon.
  • KRB5RCACHETYPE: This variable specifies the default type of replay cache to use for servers.
  • KRB5RCACHEDIR: This variable specifies the default directory for replay caches used by servers.
  • KRB5_TRACE: This variable specifies a filename to write trace log output to. Trace logs can help illuminate decisions made internally by the Kerberos libraries.
  • KRB5_CLIENT_KTNAME: This variable sets the default client keytab file name.
  • KPROP_PORT: This variable sets the default port for kprop to use.


  • ipa: This binary is the standard for managing a FreeIPA domain. It can be used to manage hosts, users, sudo rules, and much more.
  • kdestroy: The kdestroy binary is used to destroy any current Kerberos tickets in the users session.
  • kinit: The kinit binary is used to establish, or renew Kerberos tickets.
  • klist: The klist binary lists any current Kerberos tickets in use, and which principals the tickets provide access to.
  • kpasswd: The kpasswd command is used to change a Kerberos principal’s password. kpasswd first prompts for the current Kerberos password, then prompts the user twice for the new password, and the password is changed.
  • ksu: Ksu can be used as an alternative to the su binary, to switch the current user context.
  • kswitch: The kswitch command will switch the current credential cache in use.
  • kvno: The kvno binary acquires a service ticket for the specified Kerberos principals and prints out the key version numbers of each.


This is how a FreeIPA server might look like:


Since FreeIPA uses Kerberos for authentication, this process is very similar to authentication in Active Directory. In order to access resources on the domain, a user must have a valid Kerberos ticket for that resource. These tickets can be stored in a number of different locations based on the configuration of the FreeIPA domain.

CCACHE Ticket Files

When tickets are set to be stored as a file on disk, the standard format and type is a CCACHE file. This is a simple binary file format to store Kerberos credentials. These files are typically stored in /tmp and scoped with 600 permissions. From an attackers perspective this is important for the following reasons:
  1. 1.
    Valid tickets can be utilized to authenticate, without the need of the respective users plaintext password.
  2. 2.
    CCACHE tickets are highly portable. They can be downloaded and loaded onto another host without the need to renew, or validate the ticket.
Parsing a CCACHE Ticket is easily accomplished a number of different ways. The simplest method is parsing it with the klist binary.
klist /tmp/krb5cc_0
For an attacker re-using a CCACHE Ticket is very easy. To re-use a valid CCACHE Ticket, export KRB5CCNAME to the path of the valid ticket file. The system should recognize the environment variable and will attempt to use that credential material when interacting with the domain.
export KRB5CCNAME=/tmp/krb5cc_0

Unix Keyring

CCACHE Tickets **** can also be stored in **** the Linux keyring. The keyring lives inside of the kernel, and gives administrators more control over the retrieval and use of stored tickets. Tickets can be scoped in the following different ways:
  • KEYRING:name: Tickets are scoped to a specific named Keyring.
  • KEYRING:process:name: Tickets are scoped to a specific process id.
  • KEYRING:thread:name: Tickets are scoped to a specific thread.
  • KEYRING:session:name: Tickets are scoped to a specific user session.
  • KEYRING:persistent:uidnumber: Tickets are scoped to a specific user regardless of session (default).
Depending on how the administrator scoped the ticket stored inside of the Unix keyring, parsing it out may be difficult. However, the default scope for CCACHE Tickets in the Unix keyring is KEYRING:persistent:uidnumber. Fortunately if you are in the context of the user, klist can parse this information for us.
As an attacker, re-using a CCACHE Ticket stored in the Unix keyring is fairly difficult depending on how the ticket is scoped. Fortunately @Zer1t0 from @Tarlogic has built a tool that can extract Kerberos tickets from the Unix keyring. The tool is called Tickey and can be found here.


usually, each host is deployed with a keytab credential for that host that can be used to obtain a valid Credential Cache(CCACHE) Ticket Granting Ticket(TGT) for the host itself.
It consists of pairs of Kerberos principals and encrypted keys that are derived from the Kerberos password associated with the principal. Since these keys are derived from the principal’s password, if that password changes the keytab will be invalidated.
Keytab files can be used to obtain a valid ticket granting ticket (TGT) for the principal it is scoped to. This authentication process does not require the password, as it contains keys derived from the password.
Parsing a Keytab file is very easy, and can be accomplished a few ways. The easiest way to parse a keytab file is with klist. The second way utilizes a great python utility that Cody Thomas has created. His **** KeytabParser **** project will parse out the principal and its relevant encrypted keys.
Attackers can re-use credentials stored in keytab files by generating a CCACHE Ticket through the kinit binary.
# Parse keytab
klist -k /rtc/krb5.keytab
# Get TGT
kinit -kt /etc/krb5.keytab host/bastion.westeros.local@WESTEROS.LOCAL


You can find more information about how to use tickets in linux in the following link:


You could perform the enumeration via ldap and other binary tools, or connecting to the web page in the port 443 of the FreeIPA server.

Hosts, Users, and Groups

It's possible to create hosts, users and groups. Hosts and users are sorted into containers called “Host Groups” and “User Groups” respectively. These are similar to Organizational Units (OU).
By default in FreeIPA, the LDAP server allows for anonymous binds, and a large swath of data is enumerable unauthenticated. This can enumerate all data available unauthenticated:
ldapsearch -x
To get more information you need to use an authenticated session (check the Authentication section to learn how to prepare an authenticated session).
# Get all users of domain
ldapsearch -Y gssapi -b "cn=users,cn=compat,dc=domain_name,dc=local"
# Get users groups
ldapsearch -Y gssapi -b "cn=groups,cn=accounts,dc=domain_name,dc=local"
# Get all the hosts
ldapsearch -Y gssapi -b "cn=computers,cn=accounts,dc=domain_name,dc=local"
# Get hosts groups
ldapsearch -Y gssapi -b "cn=hostgroups,cn=accounts,dc=domain_name,dc=local"
From a domain joined machine you will be able to use installed binaries to enumerate the domain:
ipa user-find
ipa usergroup-find
ipa host-find
ipa host-group-find
ipa user-show <username> --all
ipa usergroup-show <user group> --all
ipa host-find <host> --all
ipa hostgroup-show <host group> --all
The admin user of FreeIPA is the equivalent to domain admins from AD.


The root user from the IPA server has access to the password hashes.
  • The password hash of a user is stored as base64 in the “userPasswordattribute. This hash might be SSHA512 (old versions of FreeIPA) or PBKDF2_SHA256.
  • The Nthash of the password store as base64 in “ipaNTHash” if system has integration with AD.
To crack these hashes:
• If freeIPA integrated with AD, ipaNTHash is easy to crack: You should decode base64 -> re-encoded it as ASCII hex -> John The Ripper or hashcat can help you to crack it fast
• If an old version of FreeIPA is used, so SSHA512 is used: You should decode base64 -> find SSHA512 hash -> John The Ripper or hashcat can help you to crack it
• If new version of FreeIPA is used, so PBKDF2_SHA256 is used: You should decode base64 -> find PBKDF2_SHA256 -> it’s length is 256 byte. John can work with 256 bits (32 byte) -> SHA-265 used as the pseudo-random function, block size is 32 byte -> you can use only first 256 bit of our PBKDF2_SHA256 hash -> John The Ripper or hashcat can help you to crack it
To extract the hashes you need to be root in the FreeIPA server, there you can use the tool dbscan to extract them:


There are the rules that grant specific permissions to users or hosts over resources (hosts, services, service groups...)
# Enumerate using ldap
ldapsearch -Y gssapi -b "cn=hbac,dc=domain_name,dc=local"
# Using ipa
ipa hbacrule-find
# Show info of rule
ipa hbacrule-show <hbacrule> --all


FreeIPA provides the ability to manage sudo permissions from one centralized source through sudo-rules. These rulesets can be used to restrict or delegate the ability to execute commands as sudo on hosts enrolled in the domain. As an attacker we can enumerate which hosts and users these rulesets are applied too, and which commands are allowed through the ruleset.
# Enumerate using ldap
ldapsearch -Y gssapi -b "cn=sudorules,cn=sudo,dc=domain_name,dc=local"
# Using ipa
ipa sudorule-find
# Show info of rule
ipa sudorule-show <sudorule> --all

Role-Based Access Control

Each role contains a set of privileges, and those respective privileges contain a set of permissions. Roles can be applied to Users, User Groups, Hosts, Host Groups, and Services. To illustrate this concept let’s discuss the default “User Administrator” role in FreeIPA.
As the screenshot above shows the “User Administrator” role contains the following privileges:
  • User Administrators
  • Group Administrators
  • Stage User Administrators
We can drill down further and enumerate the permissions delegated to each privilege:
As we can see the “User Administrator” role contains quite a lot of permissions inside of the environment. Understanding the general concept and structure of roles, privileges, and permissions can be critical to identifying attack paths throughout an environment.
# Using ldap
ldapsearch -Y gssapi -b "cn=roles,cn=accounts,dc=westeros,dc=local"
# Using ipa binary
ipa role-find
ipa role-show <role> --all
ipa privilege-find
ipa privilege-show <privilege> --all
ipa permission-find
ipa permission-show <permission> --all

Attack Scenario Example

In you can find a simple example of how to abuse some permissions to compromise the domain.



root user creation

If you can create a new user with the name root, you can impersonate him and you will be able to SSH into any machine as root.
The "User Administrators" privilege, is very powerful (as its name indicates it):
With this privilege comes a lot of different power to affect users inside the environment. Using this privilege we can make a new user inside the FreeIPA domain named _root._
Once the user is created in the domain we can obtain a ticket for the account with _kinit_.
Now we can attempt to SSH using our newly created root domain account.
As shown this drops the user into the local root account! So simply by creating a domain user for a local user we were able to authenticate using the [email protected] account and obtain the user context of the local root account.