> For the complete documentation index, see [llms.txt](https://capcap-1.gitbook.io/capcap/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://capcap-1.gitbook.io/capcap/readme/ctf-modules/exploitation/password-attacks/linux-auth-process/linux-credential-storage.md).

# Linux Credential Storage

### Overview

Linux uses **PAM (Pluggable Authentication Modules)** as the layer between login attempts and credential storage. The core module `pam_unix.so` handles authentication, session management, and password changes. It reads from and writes to two primary files: `/etc/passwd` and `/etc/shadow`.

***

### /etc/passwd

Readable by **all users and services**. One entry per user, seven colon-separated fields.

```
htb-student:x:1000:1000:,,,:/home/htb-student:/bin/bash
```

| Field          | Example             | Notes              |
| -------------- | ------------------- | ------------------ |
| Username       | `htb-student`       |                    |
| Password       | `x`                 | See values below   |
| UID            | `1000`              |                    |
| GID            | `1000`              |                    |
| GECOS          | `,,,`               | Comment/info field |
| Home directory | `/home/htb-student` |                    |
| Default shell  | `/bin/bash`         |                    |

#### Password Field Values

| Value       | Meaning                                              |
| ----------- | ---------------------------------------------------- |
| `x`         | Hash stored in `/etc/shadow` (modern default)        |
| actual hash | Old systems — crackable since file is world-readable |
| empty       | No password required to log in                       |

#### Writable /etc/passwd — Instant Root

If `/etc/passwd` is misconfigured as writable, remove the password field for root entirely:

```bash
# Before
root:x:0:0:root:/root:/bin/bash

# After (edit manually or with sed)
root::0:0:root:/root:/bin/bash
```

```bash
su
# No password prompt — drops straight into root shell
```

***

### /etc/shadow

Readable by **root only**. Stores all password hashes and password policy metadata.

```
htb-student:$y$j9T$3QSBB6CbHEu...f8Ms:18955:0:99999:7:::
```

| Field             | Example       | Meaning                                 |
| ----------------- | ------------- | --------------------------------------- |
| Username          | `htb-student` |                                         |
| Password hash     | `$y$j9T$...`  | See hash format below                   |
| Last change       | `18955`       | Days since epoch                        |
| Min age           | `0`           | Min days before password can be changed |
| Max age           | `99999`       | Days until password expires             |
| Warning period    | `7`           | Days before expiry to warn user         |
| Inactivity period | `-`           | Days after expiry before account locks  |
| Expiration date   | `-`           | Absolute account expiry date            |
| Reserved          | `-`           |                                         |

#### Hash Format

```
$<id>$<salt>$<hash>
```

| ID     | Algorithm     | Notes                                         |
| ------ | ------------- | --------------------------------------------- |
| `1`    | MD5           | Weak — billions of H/s on GPU                 |
| `2a`   | Blowfish      |                                               |
| `5`    | SHA-256       |                                               |
| `6`    | SHA-512       | Strong                                        |
| `sha1` | SHA1crypt     |                                               |
| `y`    | Yescrypt      | Modern default on Debian/Ubuntu — memory-hard |
| `gy`   | Gost-yescrypt |                                               |
| `7`    | Scrypt        |                                               |

#### Locked Accounts

If the password field starts with `!` or `*`, Unix password authentication is blocked — no typed password can ever match. However, **SSH key auth and Kerberos are unaffected** since they never consult this field.

| Prefix | Cause                                          |
| ------ | ---------------------------------------------- |
| `!`    | Manually locked (`passwd -l username`)         |
| `*`    | No password ever set (system/service accounts) |

> A locked account with an `authorized_keys` file or a Kerberos ticket is still accessible.

***

### /etc/security/opasswd

Stores **old password hashes** to prevent reuse (managed by `pam_unix.so`). Root-readable only.

```bash
sudo cat /etc/security/opasswd
# cry0l1t3:1000:2:$1$HjFAfYTG$qNDkF0zJ3v8ylCOrKB0kt0,$1$kcUjWZJX$E9uMSmiQeRh4pAAgzuvkq1
```

Key point: old entries often use **MD5 (`$1$`)** even if the system now uses Yescrypt. MD5 cracks fast, and cracked old passwords reveal patterns — users tend to reuse passwords with minor modifications across services.

***

### Cracking Linux Credentials

#### Step 1 — Backup and Unshadow

`unshadow` (bundled with John the Ripper) merges `/etc/passwd` and `/etc/shadow` into a single crackable file.

```bash
sudo cp /etc/passwd /tmp/passwd.bak
sudo cp /etc/shadow /tmp/shadow.bak
unshadow /tmp/passwd.bak /tmp/shadow.bak > /tmp/unshadowed.hashes
```

#### Step 2 — Crack with Hashcat

```bash
hashcat -m 1800 -a 0 /tmp/unshadowed.hashes rockyou.txt -o /tmp/unshadowed.cracked
```

| Flag | Value  | Meaning              |
| ---- | ------ | -------------------- |
| `-m` | `1800` | SHA-512crypt (`$6$`) |
| `-a` | `0`    | Dictionary attack    |

**Mode reference for Linux hashes:**

| Hash                 | Hashcat mode |
| -------------------- | ------------ |
| MD5crypt (`$1$`)     | `500`        |
| SHA-256crypt (`$5$`) | `7400`       |
| SHA-512crypt (`$6$`) | `1800`       |
| Yescrypt (`$y$`)     | `15700`      |

#### Step 2 (alt) — Crack with John the Ripper

JtR's **single crack mode** is built for unshadowed files — it generates candidates from the username, GECOS field, and metadata before falling back to a wordlist.

```bash
john --wordlist=rockyou.txt /tmp/unshadowed.hashes
john --show /tmp/unshadowed.hashes
```

***

### Attack Surface Summary

| File                    | Readable by | Compromise impact                                    |
| ----------------------- | ----------- | ---------------------------------------------------- |
| `/etc/passwd`           | Everyone    | Hash exposure (old systems); writable = instant root |
| `/etc/shadow`           | Root only   | All hashes exposed → offline cracking                |
| `/etc/security/opasswd` | Root only   | Old MD5 hashes + password pattern analysis           |

***

### Attack Chain (Post-Root)

```
Root access
    └── Copy /etc/passwd + /etc/shadow
            └── unshadow → merged file
                    └── hashcat / john → plaintext passwords
                            └── Password reuse across services
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://capcap-1.gitbook.io/capcap/readme/ctf-modules/exploitation/password-attacks/linux-auth-process/linux-credential-storage.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
