OSA
Task 1

Introduction

This room will guide you through the fundamentals of using, building, and refining wordlists for ethical hacking and penetration testing. Wordlists are powerful text files containing potential usernames, passwords, and directory names, and are essential tools for password cracking, directory enumeration, and other automated testing tasks.

Learning Objectives

  • Learn what wordlists are and where they're used in offensive security.
  • Discover how to gather company-specific terms and usernames using open-source intelligence (OSINT) techniques.
  • Create, clean, and deduplicate custom wordlists.
  • Use your refined lists with tools like ffuf to uncover hidden web directories and Hydra to brute-force login pages.

Prerequisites

Before starting this room, you should be comfortable with:

  • Basic Linux command-line navigation (lscat, grepsort)
  • Making HTTP requests from the terminal (curl, wget)
  • Basic web concepts: HTTP status codes and how login forms work

Follow each task in order and read the explanations carefully. By the end of this room, you'll have a solid foundation for building targeted wordlists and using them effectively during engagements.

?Answer the questions below

  1. I’m ready to learn about wordlists!
Task 2

Wordlists

A wordlist is simply a text file where each line contains a potential word, phrase, password, filename, or other string. In cyber security, these lists are used for automated guessing: instead of a human trying thousands of possible passwords, a tool feeds each entry from the file into a login form or a search field. Wordlists are valuable in many stages of penetration testing. They might contain common passwords (such as those leaked in breaches), English dictionary words, words relevant to the target's environment, or lists of likely sub-domains.

Wordlists are fundamental to many cyberattacks and security assessments, especially password cracking and enumeration attacks. They are used in brute-force attacks, where every entry in the file is tried as a password, dictionary attacks, which use real words and frequently used passwords, and directory or file enumeration, where the list contains possible folder or file names to locate hidden resources on a web server.

Where Are Wordlists Used?

  • Password guessing and cracking: Password-cracking tools such as John the Ripper and hashcat iterate through a wordlist to find the correct password.
  • Service login brute-forcing: Tools like Hydra and Medusa test username/password combinations against SSH, FTP, or HTTP. Hydra uses wordlists to attempt logins to various network services.
  • Directory brute-forcing: A web directory scanner (DirBuster, Gobuster, ffuf) reads a list of standard file and directory names and tests each against a web server. DirBuster, for example, uses wordlists of common filenames and paths to find exposed files and directories. The SecLists collection contains specific wordlists for this purpose.
  • Subdomain discovery: DNS enumeration tools such as DNSRecon, Sublist3r, and ffuf use lists of possible subdomain names to find additional hosts. SecLists provides lists such as subdomains-top1million-5000.txt for fast scanning.

Common Tools That Use Wordlists

Tool Purpose How it uses wordlists
John the Ripper Password cracking Performs dictionary attacks on password hashes using wordlists of common passwords.
hashcat Password cracking Uses wordlists and rule-based mutations to crack password hashes.
Hydra Network service login brute-forcing Feeds username/password wordlists into login prompts across many protocols.
Gobuster / ffuf Directory and subdomain enumeration Reads wordlists of directory names or sub-domains and sends requests to discover hidden resources.
Burp Suite / OWASP ZAP Web fuzzing Uses wordlists to fuzz parameters, cookies, and headers for vulnerability discovery.
Aircrack-ng Wireless password cracking Uses wordlists to guess WPA/WPA2 passphrases.

Common Wordlist Sources

  • Pre-made wordlists: Some well-known lists come bundled with penetration-testing distributions. The rockyou.txt wordlist is provided by Kali Linux and contains over 14 million commonly used passwords. The Kali package page shows that rockyou.txt is included under /usr/share/wordlists/ and the uncompressed file has 14,344,392 lines. Another essential collection is SecLists, a broad set of lists covering usernames, passwords, directories, API endpoints, and attack payloads. SecLists includes lists tailored for web content discovery (raft-large-files.txt, common.txt), password cracking (top-passwords-shortlist.txt, rockyou.txt), DNS (subdomains-top1million-5000.txt) and many other scenarios.
  • Custom wordlists: While pre-made lists provide breadth, custom lists tailored to the target often yield better results. Customised lists can include personal information, local language, industry-specific terms, or cultural references. Gathering targeted words reduces noise and increases the chance of guessing real credentials.
  • Automated wordlist generators: When you know a password pattern or want to exhaust all combinations of a character set, a generator like crunch can create the list for you. Crunch takes a minimum and maximum length, and an optional character set, and outputs every possible string that meets those criteria. According to the Kali tool documentation, Crunch is a wordlist generator that can use lowercase and uppercase letters, numbers and symbols separately to generate lists of a defined size. For example, the command crunch 6 6 0123456789abcdef -o 6chars.txt produces every six-character string from the hexadecimal character set and writes it to a file. 
    Crunch can also send its output to another program, letting you pipe generated passwords directly into tools like Hydra or John the Ripper. While effective, combinatorial generators should be used judiciously because they produce very large files; targeted custom lists built from OSINT often yield more efficient results.

?Answer the questions below

  1. What tool can generate a custom wordlist based on known patterns?
Task 3

Gathering Information for Custom Wordlists

Lab Setup

Before you dive into the exercises, please make sure your lab environment is ready. You can use the AttackBox or your own VM connected to the VPN. You can start your machines with the buttons included below. Once both machines are running, you'll have all the necessary tools, such as CeWL, crunch, grep, Hydra, and ffuf, to complete this room.

Once the target machine has booted up and you have its IP address, run the following command to add the necessary entries to your /etc/hosts file so that domain names resolve correctly:

Add IP to /etc/hosts
user@tryhackme:~$ echo 'MACHINE_IP tryfinanceme.local social.tryfinanceme.local' >> /etc/hosts    

Creating an effective custom wordlist begins with information gathering. Generic lists often miss company-specific or technology-specific terms, and a good custom list should include three categories:

  • Company-specific keywords: product names, internal features, or project code names
  • Technology-specific keywords: terms based on the frameworks or languages used (e.g., WordPress plugins, Laravel routes)
  • Generic keywords: common folders and API routes such as api, assets, admin, dev, login, and settings

Combining these categories helps us uncover hidden directories, parameters and sub-domains that generic wordlists miss.

To build these lists, we must collect public details about the target organisation or individual. By harvesting names, products, locations, or hobbies from OSINT sources, we can derive candidate words that are likely to appear in passwords, subdomains, or directory names. This activity is sometimes called harvesting.

Simple OSINT Sources

  • Professional networks: Employee names, job titles, and technologies from LinkedIn, company pages, or recruitment sites can reveal naming patterns. MITRE ATT&CK catalogues this under T1591.004 Identify Roles, recognising employee names, roles, and job descriptions as reconnaissance sources that expose tools, technologies, and internal processes. Tools like linkedin2username or CrossLinked automate employee enumeration.
  • Company websites and social media: Corporate websites often mention project names, product names, office locations, and slogans. Social media accounts (Twitter/X, Facebook, GitHub) may reveal hashtags, internal acronyms, or services used. Data gathered from profiles, connections, and posts on platforms like LinkedIn, Facebook, Twitter, and GitHub can feed social engineering attacks and expand the attack surface.
  • Job advertisements: Job postings describe a company's technologies. Phrases like "AWS", "Salesforce", or "React" may appear in internal sub-domains or directories. Searching for the company and adding the term "jobs," or using sites like Indeed or LinkedIn Jobs, can provide these results.

Basic Recon Methods

  • WHOIS lookup: A WHOIS search reveals domain registration details, nameservers, and sometimes contact information for IT staff. WHOIS databases provide the organisation's name and the DNS servers hosting its data. Tools like whois are pre-installed on Kali Linux.
  • Subdomain enumeration and certificate search: Tools like theHarvester, Sublist3r, and Recon-ng extract subdomains and email addresses from public sources. Certificate transparency logs (e.g., crt.sh) and passive DNS services can reveal historical domain names.
  • Site crawling: Crawling the target website can collect words used in pages, meta-tags, or documents. The CeWL tool automates this by spidering pages and extracting words.
  • Technology fingerprinting: To generate technology-specific keywords, fingerprint the target's technology stack. You can use tools like BuiltWith or Wappalyzer, or read HTTP headers to identify frameworks, languages, or CMSs. Once you know the technology, browse SecLists for lists tailored to those platforms (e.g., WordPress plugin paths or API routes). This approach helps you include relevant directory names and endpoints that generic lists omit.

Tools and Techniques for Gathering Words

Before following along with the commands below, ensure both machines are running as instructed at the beginning of this task.

Cewl: Crawling for Words and Emails

CeWL is a Ruby tool that spiders a URL and extracts unique words from the target. It can also harvest email addresses with the -e flag. We'll use it to collect company-specific terms from the TryFinanceMe site.

CeWL Wordlist Generation
           user@tryhackme:~$ cewl -d 2 -m 3 --lowercase --with-numbers -e --email_file emails.txt -w cewl_words.txt http://tryfinanceme.local

CeWL 6.2.1 (More Fixes) Robin Wood (robin@digi.ninja) (https://digi.ninja/)
        

Flags explained:

  • -d 2: Spider two levels deep.
  • -m 3: Only include words with three or more characters.
  • --lowercase: Convert all extracted words to lowercase.
  • --with-numbers: Include words that contain numbers.
  • -e: Enable email extraction.
  • --email_file emails.txt: Save found emails to emails.txt.
  • -w cewl_words.txt: Save extracted words to cewl_words.txt.
  • http://tryfinanceme.local: Target URL for crawling.

This produces two useful lists: cewl_words.txt (keywords) and emails.txt (full company emails). 

Downloading Documents and Extracting Strings

Next, look for any hosted documents. Many organisations publish PDFs and docs that contain internal jargon or even credentials. In TryFinanceMe's environment, the /docs directory hosts PDFs. Recursively download these files and extract human-readable strings:

Downloading PDFs
           user@tryhackme:~$ wget -r -A pdf http://tryfinanceme.local/docs/
--2025-08-13 09:25:37-- http://tryfinanceme.local/docs/ Resolving tryfinanceme.local (tryfinanceme.local)... 10.10.32.241 Connecting to tryfinanceme.local (tryfinanceme.local)|10.10.32.241|:80... connected. HTTP request sent, awaiting response... 200 OK
[
...] user@tryhackme:~$ for f in $(find tryfinanceme.local/docs -name '*.pdf'); do strings -n 5 "$f" | grep -vP '^[/<>%0-9\\]|^(stream|endstream|endobj|xref|trailer|startxref)$' >> raw_words.txt; done

Extracting Emails From Downloaded PDFs

PDFs often include contact emails in footers or author fields. Extract any email addresses from the downloaded docs and turn them into usernames:

Extracting Emails from PDFs
           user@tryhackme:~$ grep -RhiaoP '[A-Za-z0-9._%+-]+@tryfinanceme\.com' tryfinanceme.local/docs > emails_docs.txt
user@tryhackme:~$ sort -u emails_docs.txt > emails_docs.unique.txt
user@tryhackme:~$ grep -Po '^[^@]+' emails_docs.unique.txt > users_from_emails.txt
        

Here's what each line does:

  • The regex grep looks recursively through the downloaded files for any string that matches username@tryfinanceme.com and writes the result to emails_docs.txt.
  • sort -u removes duplicate email addresses.
  • A second grep strips off the domain portion (@tryfinanceme.com), leaving you with just the local part. These will form a portion of your username list.

Harvesting Names From the Social Page

Real people's names often appear in email addresses and login IDs. On social.tryfinanceme.local, each profile name appears in the HTML as:

Source Code
           <h3 class="profile-name">Alex Johnson</h3>
        

A precise regex will extract these names without grabbing other text:

Harvesting Names from Social Page
           user@tryhackme:~$ curl -s http://social.tryfinanceme.local/ | grep -Po '(?<=<h3 class="profile-name">)[^<]+' > names.txt

        

The pattern uses a positive lookbehind to anchor right after the opening tag (<h3 class="profile-name">). It then matches any characters except < until the closing tag. You end up with a clean list of names.

Transform these names into likely username patterns:

Generating Username Formats
           user@tryhackme:~$ awk '{print tolower($1)"."tolower($2)}' names.txt > users_first.last.txt
user@tryhackme:~$ awk '{print tolower(substr($1,1,1))tolower($2)}' names.txt > users_flast.txt
user@tryhackme:~$ awk '{print tolower($1)tolower(substr($2,1,1))}' names.txt > users_firstl.txt
        

We use awk to split each full name into first and last components and build three common username formats. For "Alex Johnson", these produce:

  • users_first.last.txt: first name, dot, last name, e.g., alex.johnson
  • users_flast.txt: first initial + last name, e.g., ajohnson
  • users_firstl.txt: first name + last initial, e.g., alexj

Converting to lowercase avoids case mismatches.

Summary of gathered files so far:

  • cewl_words.txt: Keywords from the website.
  • emails.txt: Emails discovered by CeWL.
  • raw_words.txt: Strings extracted from PDFs.
  • emails_docs.txt: Emails found in PDFs.
  • names.txt: Employee names from the social page.
  • users_first.last.txt, users_flast.txt, users_firstl.txt: Username permutations.
  • users_from_emails.txt: Usernames extracted from emails.

?Answer the questions below

  1. After running the CeWL command shown in the task, how many unique email addresses did you scrape?
  2. How many PDF files were you able to find?
  3. How many email addresses (or new emails) were you able to extract from the PDF files?
  4. What is the last username in the users_from_emails.txt file?
Task 4

Creating and Cleaning Wordlists

By now, you should have a set of raw wordlists and username candidates from various sources. Raw lists are often messy: they contain duplicates, mixed case, and irrelevant strings. Cleaning transforms this jumble into tidy, deduplicated lists that enumeration tools can digest.

Why Cleaning Matters

A bloated, unfiltered wordlist wastes time. Directories called #include or strings containing punctuation are unlikely to exist on a web server. Duplicate entries slow down brute forcing without adding value. Lowercasing everything reduces fragmentation because Helios, helios and HELios all refer to the same string. Filtering out very short or complex tokens focuses your enumeration on plausible paths. Finally, previewing and counting your lists helps you judge whether they’re too large or too small.

Merging and Normalising Password Words

First, combine the words scraped from the site (cewl_words.txt) and the strings extracted from PDFs (raw_words.txt). Sorting and removing duplicates yields a cleaner starting point:

Merging Word Lists
           user@tryhackme:~$ cat cewl_words.txt raw_words.txt | sort -u > words_raw.txt

        

sort -u sorts lines alphabetically and discards duplicates. Even after de‑duplication, the list might include uppercase words, carriage returns from Windows documents, and short or malformed strings. Apply a second pass to normalise and filter:

Normalising and Filtering
           user@tryhackme:~$ cat words_raw.txt | tr '[:upper:]' '[:lower:]' | tr -d '\r' | grep -P '^[a-z0-9][a-z0-9._-]{4,}$' | sort -u > words_clean.txt

        
  • tr '[:upper:]' '[:lower:]': Converts uppercase to lowercase.
  • tr -d '\r': Strips Windows carriage returns.
  • The grep pattern keeps strings that start with an alphanumeric character, then allow letters, digits, dots, underscores or dashes, and are at least five characters long. This removes many noise entries.
  • A final sort -u ensures uniqueness.

Check the size and get a feel for the contents:

Checking Password List
           user@tryhackme:~$ wc -l words_clean.txt
user@tryhackme:~$ head words_clean.txt
about
access
account
accuracy
advanced
analysis
analyst
analytics
analyze
assessment

A huge list will slow down ffuf; a small one may miss legitimate paths. You should see a few hundred entries, all lowercase and well‑formed.

Merging and Normalising Usernames

Usernames collected from emails and names need to be deduplicated as well. Merge all variations and remove duplicates:

Merging Username Lists
           user@tryhackme:~$ cat users_first.last.txt users_flast.txt users_firstl.txt users_from_emails.txt | sort -u > users.txt
        

Generating a Pattern‑Based Password List

So far, your wordlist covers directory and file discovery. For cracking the login form, you need a focused password list. During OSINT, you learned that Helios passwords follow Helios20NN! where NN are digits. A combinatorial generator like Crunch can exhaust this space efficiently:

"Generating Pattern Passwords
           user@tryhackme:~$ crunch 11 11 -t Helios20%%! -o pass_helios.txt

        
  • The two 11 arguments set the minimum and maximum length to 11 characters.
  • -t: Defines a pattern where %% are replaced by digits (00 through 99).
  • -o pass_helios.txt: Writes 100 entries to disk.

This list is tiny, which makes Hydra run quickly. If you discover later that passwords follow a different format, adjust the pattern accordingly (e.g., a different year or more digits).

At this stage, you should have two clean lists ready for use:

  • words_clean.txt: For discovering directories and files.
  • users.txt and pass_helios.txt: For brute‑forcing the login form.

?Answer the questions below

  1. How many words are in words_clean.txt after cleaning up the file?
  2. What is the 10th password in the pass_helios.txt file?
  3. What flag does sort use to remove duplicate lines?
  4. What crunch template character represents a digit?
Task 5

Using Your Wordlist

With clean lists ready, we'll use our directory wordlist to find hidden paths on TryFinanceMe, then use the username and password lists to crack the login page.

Directory and File Discovery With Ffuf

Directory enumeration answers the question: What resources exist on the web server that are not linked publicly? Tools like ffuf take a list of potential paths and append each to a base URL. They then interpret the HTTP response codes to decide whether something exists.

We use words_clean.txt here because it contains the company-specific terms we scraped in Task 3, exactly the kind of words likely to appear as hidden directory names. Run ffuf like this:

Directory Fuzzing
           user@tryhackme:~$ ffuf -w words_clean.txt -u http://tryfinanceme.local/FUZZ -e .php,.html,/ -mc 200,301,302

        

Flags explained:

  • -w words_clean.txt: Path to the wordlist.
  • -u http://tryfinanceme.local/FUZZ: Target URL; ffuf replaces FUZZ with each word from the list.
  • -e .php,.html,/: Test each word as-is and with these extensions appended.
  • -mc 200,301,302: Only report responses with these status codes.

Here, ffuf will test each word as-is and with the extensions .php, .html, and /, and report only HTTP 200, 301, or 302 responses (i.e., valid pages or redirects). When we scroll through the output, we should spot an entry called helios/. If we see hundreds of false positives, add -fs <bytes> (filter by response size) or -fl <lines> (filter by line count) after noting the size or line count of a typical 404 response.

ffuf can do more: we can also use it to discover subdomains, parameters, or API endpoints by adjusting the URL pattern and wordlist. For this lab we limit ourselves to directories.

Brute-Forcing the Login Page With Hydra

Once we know the hidden directory, navigate to it. We will find a login form at http://tryfinanceme.local/helios/login.php. Hydra can send HTTP POST requests and iterate through combinations of usernames and passwords.

The http-post-form module takes the form specification as its argument, with three colon-separated parts:

  1. /helios/login.php: The path to the login handler.
  2. username=^USER^&password=^PASS^: The POST body, using Hydra's ^USER^ and ^PASS^ placeholders.
  3. S=THM{: A success condition. Hydra considers the login successful if the HTTP response contains THM{. This is specific to our lab, where the flag appears upon successful login.
Hydra Brute Force
           user@tryhackme:~$ hydra -L users.txt -P pass_helios.txt -f -V -t 4 tryfinanceme.local http-post-form '/helios/login.php:username=^USER^&password=^PASS^:S=THM{'

[DATA] attacking http-post-form://tryfinanceme.local:80/helios/login.php:username=^USER^&password=^PASS^:S=THM{
[80][http-post-form] host: tryfinanceme.local   login: ****.*****   password: *********
1 of 1 target successfully completed, 1 valid password found
        

Flags explained:

  • -L users.txt: Read usernames from a file.
  • -P pass_helios.txt: Read passwords from a file.
  • -f: Stop after the first valid credential is found.
  • -V: Print each attempt.
  • -t 4: Use four threads; increase cautiously if more speed is needed.

Hydra will print each username/password pair it tries. When a line appears showing a login, note the correct credentials. We can now open http://tryfinanceme.local/helios/ in our browser, log in with the discovered username and password, and reveal the flag.

?Answer the questions below

  1. What HTTP status code does ffuf report for helios/ ?
  2. What is the username that Hydra discovers?
  3. What is the flag?
Task 6

Conclusion

Great job completing Introduction to Wordlists! Over the course of this room, we:

  • Explored what wordlists are, how they're used, and why generic lists often fall short.
  • Used OSINT techniques, such as harvesting names from social media, WHOIS lookups, and site crawling, to create company-specific lists.
  • Combined and cleaned our raw lists, then applied filters to remove duplicates, normalise the case, and eliminate noise.
  • Generated pattern-based passwords with crunch, merged multiple username formats, and prepared clean words_clean.txt, users.txt, and pass_helios.txt files.
  • Used ffuf to discover hidden directories on the target website and employed Hydra to brute-force the login form using our custom lists.

By tailoring our wordlists to the target and keeping them clean, we improve efficiency and success rates when conducting enumeration or password-cracking tasks. Remember that these techniques should always be used responsibly and only against systems we're authorised to test. We can continue practising these skills in other rooms and experiment with additional tools and sources to further sharpen our custom-wordlist workflow.

?Answer the questions below

  1. I got all my wordlists sharp and ready.