hacktricks/linux-hardening/freeipa-pentesting.md
carlospolop f0e09e3f54 social
2023-03-06 00:16:20 +01:00

314 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# FreeIPA Pentesting
<details>
<summary><strong>HackTricks in </strong><a href="https://twitter.com/carlospolopm"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch</strong></a> <strong>Wed - 18.30(UTC) 🎙️</strong> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).
</details>
This info was taken from the posts:
* [https://posts.specterops.io/attacking-freeipa-part-i-authentication-77e73d837d6a](https://posts.specterops.io/attacking-freeipa-part-i-authentication-77e73d837d6a)
* [https://posts.specterops.io/attacking-freeipa-part-ii-enumeration-ad27224371e1](https://posts.specterops.io/attacking-freeipa-part-ii-enumeration-ad27224371e1)
* [https://www.youtube.com/watch?v=9dOu-7BTwPQ\&feature=youtu.be](https://www.youtube.com/watch?v=9dOu-7BTwPQ\&feature=youtu.be)
## 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.
## Fingerprints
### 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.
### Binaries
* **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 principals 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.
### Network
This is how a FreeIPA server might look like:
<figure><img src="../.gitbook/assets/image (197).png" alt=""><figcaption></figcaption></figure>
## Authentication
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 v**alid 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. Valid tickets can be **utilized to authenticate**, **without** the need of the respective users plaintext **password**.
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
```
<figure><img src="../.gitbook/assets/image (70).png" alt=""><figcaption></figcaption></figure>
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.
```bash
export KRB5CCNAME=/tmp/krb5cc_0
klist
```
<figure><img src="../.gitbook/assets/image (175).png" alt=""><figcaption></figcaption></figure>
### **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.
<figure><img src="../.gitbook/assets/image (3) (1) (4).png" alt=""><figcaption></figcaption></figure>
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](https://github.com/Zer1t0) from [@Tarlogic](https://twitter.com/Tarlogic) has built a tool that can extract Kerberos tickets from the Unix keyring. The tool is called **Tickey** and can be found [**here**](https://github.com/TarlogicSecurity/tickey).
<figure><img src="../.gitbook/assets/image (185).png" alt=""><figcaption></figcaption></figure>
### Keytab <a href="#ff38" id="ff38"></a>
{% hint style="warning" %}
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.
{% endhint %}
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 principals 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](https://medium.com/u/645ffcef8682?source=post\_page-----77e73d837d6a--------------------------------) has created. His \*\*\*\* [**KeytabParser**](https://github.com/its-a-feature/KeytabParser) \*\*\*\* project will parse out the principal and its relevant encrypted keys.
<figure><img src="../.gitbook/assets/image (200).png" alt=""><figcaption></figcaption></figure>
Attackers can **re-use credentials stored in keytab files by generating a CCACHE Ticket** through the kinit binary.
```powershell
# Parse keytab
klist -k /rtc/krb5.keytab
# Get TGT
kinit -kt /etc/krb5.keytab host/bastion.westeros.local@WESTEROS.LOCAL
```
<figure><img src="../.gitbook/assets/image (205).png" alt=""><figcaption></figcaption></figure>
### Cheatsheet
You can find more information about how to use tickets in linux in the following link:
{% content-ref url="privilege-escalation/linux-active-directory.md" %}
[linux-active-directory.md](privilege-escalation/linux-active-directory.md)
{% endcontent-ref %}
## Enumeration
{% hint style="warning" %}
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**.
{% endhint %}
<figure><img src="../.gitbook/assets/image (184).png" alt=""><figcaption></figcaption></figure>
### Hosts, Users, and Groups <a href="#4b3b" id="4b3b"></a>
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).
```bash
# 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:
```bash
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
```
{% hint style="info" %}
The **admin** user of **FreeIPA** is the equivalent to **domain admins** from **AD**.
{% endhint %}
### Hashes <a href="#482b" id="482b"></a>
The **root** user from the **IPA serve**r has access to the password **hashes**.
* The password hash of a user is stored as **base64** in the “**userPassword**” **attribute**. 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 -> its **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
<figure><img src="../.gitbook/assets/image (33).png" alt=""><figcaption></figcaption></figure>
To extract the hashes you need to be **root in the FreeIPA server**, there you can use the tool **`dbscan`** to extract them:
<figure><img src="../.gitbook/assets/image (196).png" alt=""><figcaption></figcaption></figure>
### HBAC-Rules <a href="#482b" id="482b"></a>
There are the rules that grant specific permissions to users or hosts over resources (hosts, services, service groups...)
```bash
# 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
```
#### Sudo-Rules
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.
```bash
# 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 lets discuss the default “User Administrator” role in FreeIPA.
<figure><img src="../.gitbook/assets/image (161).png" alt=""><figcaption></figcaption></figure>
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**:
<figure><img src="../.gitbook/assets/image (189).png" alt=""><figcaption></figcaption></figure>
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.
```bash
# 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 [https://posts.specterops.io/attacking-freeipa-part-iii-finding-a-path-677405b5b95e](https://posts.specterops.io/attacking-freeipa-part-iii-finding-a-path-677405b5b95e) you can find a simple example of how to abuse some permissions to compromise the domain.
## Privesc
### ~~root user creation~~
{% hint style="warning" %}
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.**
**THIS HAS BEEN PATCHED.**
{% endhint %}
The "**User Administrators**" privilege, is very powerful (as its name indicates it):
<figure><img src="../.gitbook/assets/image (182).png" alt=""><figcaption></figcaption></figure>
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**.\_
<figure><img src="../.gitbook/assets/image (158).png" alt=""><figcaption></figcaption></figure>
Once the user is created in the domain we can **obtain a ticket for the account with \_kinit**\_.
<figure><img src="../.gitbook/assets/image (178).png" alt=""><figcaption></figcaption></figure>
Now we can attempt to **SSH** using our newly created root domain account.
<figure><img src="../.gitbook/assets/image (176).png" alt=""><figcaption></figcaption></figure>
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 _root@WESTEROS.LOCAL_ account and obtain the **user context of the local root account**_._
_For more details about this vuln check_ [_https://posts.specterops.io/attacking-freeipa-part-iv-cve-2020-10747-7c373a1bf66b_](https://posts.specterops.io/attacking-freeipa-part-iv-cve-2020-10747-7c373a1bf66b)\\
<details>
<summary><strong>HackTricks in </strong><a href="https://twitter.com/carlospolopm"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch</strong></a> <strong>Wed - 18.30(UTC) 🎙️</strong> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).
</details>