mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-24 12:03:37 +00:00
314 lines
20 KiB
Markdown
314 lines
20 KiB
Markdown
# 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 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.
|
||
|
||
### 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 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](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 -> 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
|
||
|
||
<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 let’s 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>
|