Cred Hunter
Cred Hunter
Platform: HackTheBox | Category: Misc | Type: Challenge | Difficulty: Easy | OS: NA | Author: D3v0o0Nu11 | Date: 2026-02-01 | Status: Solved Techniques: email_parsing, lexicographic_sorting, substring_search
Summary
Task: Parse mixed emails and passwords, find valid credential pairs where the firstname from the email appears as a substring in the password. Solution: Extract firstname from email local part (all chars except last), check substring match against all passwords, sort pairs lexicographically.
Recon
Port scan
bash read-only • copy allowednmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
hackthebox| ID:20260201_hackthebox_cred_hunter - Tags: regex, parsing, string_matching, credential_pairing
- Indicators: email format parsing, firstname extraction, substring matching, credential pairing
- Source:
20260201_hackthebox_cred_hunter.md
Foothold
Vulnerability / Misconfiguration
- email_parsing
- lexicographic_sorting
- substring_search
bash read-only • copy allowed<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
bash read-only • copy allowedsudo -l find / -perm -4000 2>/dev/null getcap -r / 2>/dev/null cat /etc/crontab ps aux
Exploitation
- N/A for challenge-type writeup; see exploitation above.
- Flag obtained via challenge solve.
bash read-only • copy allowed<command>
Flags
| Flag | Location | Value |
|---|---|---|
| flag | REDACTED |
Key Takeaways / Lessons
- email_parsing
- lexicographic_sorting
- substring_search
- Tags: regex, parsing, string_matching, credential_pairing
Original Writeup
<details><summary>Click to expand original content</summary>Challenge Info
| Field | Value |
|---|---|
| Event | HackTheBox |
| Category | Programming/Misc |
| Difficulty | Easy |
| Target | 94.237.56.175:43741 |
| Flag | HTB{REDACTED} |
Description
The data leaked quietly - unnoticed, unguarded, and brimming with opportunity. You're in deep now. A tangle of credentials spilled from a forgotten system connected to CygnusCorp's sprawling digital perimeter. Half garbage, half gold. Somewhere in this chaos are access keys - real names, real logins, real passwords. You just have to find the ones that match.
Analysis
This is a web-based coding challenge using Monaco editor interface. The task involves:
- Input: N strings containing a mix of emails and passwords
- Email Format: CygnusCorp uses
firstname + first_letter_of_lastname@domain- Example:
alicej@cygnus.com(Alice J.) - Example:
joshr@cygnuscorp.eu(Josh R.)
- Example:
- Valid Pair: An (email, password) pair is valid when the firstname (extracted from email) appears as a substring in the password
- Output: All valid pairs sorted lexicographically by email, then by password
Key Insight
The email format firstnameX@domain means:
- Local part =
firstname+first_letter_of_lastname - Therefore:
firstname = local_part[:-1](remove last character)
For example:
lisabethf@cygnuscloud.com-> firstname =lisabethnevinn@cygnus.com-> firstname =nevinjoicep@cygnusdevs.eu-> firstname =joice
Solution
Algorithm
- Parse input - Read N strings
- Classify strings - Separate emails from passwords using regex
- Extract firstnames - For each email, get
local_part[:-1] - Find pairs - For each (email, password) combination, check if firstname is substring of password
- Sort and output - Sort pairs lexicographically (email first, then password)
Python Solution
python read-only • copy allowedimport re def solve(): n = int(input()) lines = [] for _ in range(n): lines.append(input().strip()) # Email pattern: firstname + first letter of lastname @ domain email_pattern = re.compile(r"^[a-z]+@[a-z0-9.-]+\.[a-z]{2,}$", re.IGNORECASE) emails = [] passwords = [] for line in lines: if "@" in line and email_pattern.match(line): local_part = line.split("@")[0] if len(local_part) >= 2: firstname = local_part[:-1] # All except last letter emails.append((line, firstname)) else: passwords.append(line) pairs = [] for email, firstname in emails: for password in passwords: if firstname in password: pairs.append((email, password)) pairs.sort(key=lambda x: (x[0], x[1])) for email, password in pairs: print(f"{email} {password}") solve()
Example Walkthrough
Input:
17
lisabethf@cygnuscloud.com
nevin2024!@
nevinn@cygnus.com
...
joicep@cygnusdevs.eu
2025joiceTheDev!@
Processing:
lisabethf@cygnuscloud.com-> firstname =lisabethnevinn@cygnus.com-> firstname =nevinjoicep@cygnusdevs.eu-> firstname =joice
Matching:
lisabethfound inlisabeth2024-> valid pairnevinfound innevin2024!@-> valid pairjoicefound in2025joiceTheDev!@andjoiceqwerty2025-> two valid pairs
Output (sorted):
joicep@cygnusdevs.eu 2025joiceTheDev!@
joicep@cygnusdevs.eu joiceqwerty2025
lisabethf@cygnuscloud.com lisabeth2024
nevinn@cygnus.com nevin2024!@
Complexity Analysis
- Time: O(N^2 * M) where N = number of strings, M = average string length
- Separating emails/passwords: O(N)
- Checking all pairs: O(emails * passwords * avg_length)
- Space: O(N) for storing emails and passwords
Given constraints (N <= 10^4), the O(N^2) approach is acceptable.
Lessons Learned
- Email parsing - Understanding corporate email naming conventions can reveal personal information
- Credential correlation - Users often include their name/username in passwords (bad practice!)
- Simple solutions work - O(N^2) brute force is often sufficient for CTF constraints
- Case sensitivity matters - The matching was case-sensitive (no
.lower()needed)
signed by XESXOR