Skip to content

update ui & add multi-threading#39

Open
MoDarK-MK wants to merge 4 commits intoAntu7:masterfrom
MoDarK-MK:pr-branch
Open

update ui & add multi-threading#39
MoDarK-MK wants to merge 4 commits intoAntu7:masterfrom
MoDarK-MK:pr-branch

Conversation

@MoDarK-MK
Copy link
Copy Markdown

No description provided.

MoDarK-MK and others added 4 commits April 11, 2026 01:26
- Merged upstream changes
- Resolved conflicts in README.md, requirements.txt, bruteforce.py
- Added Rich library integration
- Applied hacker theme with green styling
- Enhanced UI with panels, tables, and progress bars
- Updated README with recent updates section
Copilot AI review requested due to automatic review settings April 10, 2026 22:30
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the terminal UI to use the Rich library and introduces a CLI argument parsing flow intended to support automated/non-interactive runs.

Changes:

  • Add rich as a dependency and rework terminal output (banner, prompts, tables, results) to use Rich styling.
  • Add argparse-based CLI flags and split the run flow into automated vs interactive modes.
  • Update README to mention Rich UI enhancements and add a “Recent Updates” section.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 8 comments.

File Description
requirements.txt Adds the rich dependency needed for the new terminal UI.
README.md Updates feature bullet(s) and adds release notes, but currently diverges from the tool’s actual behavior.
bruteforce.py Replaces ANSI UI with Rich, adds CLI parsing and refactors main flow; introduces a few functional regressions/bugs to address.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 9 to +32
@@ -13,67 +14,184 @@
import re
import os
import secrets
import argparse
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor, as_completed
from urllib.parse import urljoin, urlparse
from rich.console import Console
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn, TimeElapsedColumn
from rich.panel import Panel
from rich.text import Text
from rich.table import Table
from rich.live import Live
from rich.layout import Layout
from rich.syntax import Syntax
from rich.align import Align
from rich.style import Style
import sys
import os
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bruteforce.py now imports sys and os twice, and several Rich-related imports (e.g., Progress, SpinnerColumn, Text, Live, Layout, Syntax, Align, Style) plus urljoin are unused in this file. This adds noise and can fail linting in environments that enforce unused-import checks; please remove duplicates and any unused imports (or start using them).

Copilot uses AI. Check for mistakes.
WHITE = '\033[97m'
# Configure encoding for Windows compatibility
if sys.platform == 'win32':
os.environ['PYTHONIOENCODING'] = 'utf-8'
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting PYTHONIOENCODING at runtime won’t change the encoding of already-initialized stdio streams (Python reads it at interpreter startup). If the intent is to fix Windows Unicode output, reconfigure sys.stdout/sys.stderr encoding (or avoid relying on this env var) so the workaround is actually effective.

Suggested change
os.environ['PYTHONIOENCODING'] = 'utf-8'
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(encoding='utf-8')
if hasattr(sys.stderr, "reconfigure"):
sys.stderr.reconfigure(encoding='utf-8')

Copilot uses AI. Check for mistakes.
Comment on lines 395 to 414
@@ -523,7 +410,7 @@ def crack_password_wrapper(password, cracker, state):

# Update progress (overwrite same line)
total = state['total']
sys.stdout.write(f"\r {C.BLUE}[*]{C.RESET} {progress_bar(current, total)} Current: {password[:20]:<20}")
sys.stdout.write(f"\r[*] {progress_bar(current, total)} {password[:20]:<20}")
sys.stdout.flush()
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

progress_bar() now returns Rich markup (e.g. [bright_cyan]...[/]), but the caller writes it via sys.stdout.write, so the markup will be printed literally instead of being styled. Either render the progress output via console.print(..., end="") / Rich Progress, or return plain-text characters when using sys.stdout.write.

Copilot uses AI. Check for mistakes.
Comment on lines 403 to 414
@@ -523,7 +410,7 @@ def crack_password_wrapper(password, cracker, state):

# Update progress (overwrite same line)
total = state['total']
sys.stdout.write(f"\r {C.BLUE}[*]{C.RESET} {progress_bar(current, total)} Current: {password[:20]:<20}")
sys.stdout.write(f"\r[*] {progress_bar(current, total)} {password[:20]:<20}")
sys.stdout.flush()
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crack_password_wrapper updates progress output from worker threads without synchronizing stdout writes. With multiple threads this will interleave \r writes and produce garbled output (and potentially slow the attack due to heavy console I/O). Consider emitting progress only from the main thread (while iterating as_completed) or guard the stdout write with a lock shared across workers.

Copilot uses AI. Check for mistakes.
Comment on lines +455 to +506
parser.add_argument('--username-field', type=str, help='Override auto-detected username field name')
parser.add_argument('--password-field', type=str, help='Override auto-detected password field name')
parser.add_argument('--api-endpoint', type=str, help='Override auto-detected API endpoint (for JSON API mode)')
parser.add_argument('--login-mode', choices=['form', 'api'], help='Force login mode instead of auto-detecting')

return parser.parse_args()


def main():
# Parse arguments FIRST before showing banner
args = parse_arguments()

# Show banner only for interactive mode or first automated call
banner()

section("STEP 1 — TARGET INFO")
print()

# Check if running in automated mode or interactive mode
if args.url and args.username and args.error:
# Automated mode - run with provided arguments (banner already shown)
run_attack_automated(args, show_banner=False)
else:
# Interactive mode - prompt user for input (banner already shown)
run_attack_interactive(show_banner=False)


def run_attack_automated(args, show_banner=True):
"""Run attack in fully automated mode using command-line arguments."""
if show_banner:
banner()

url = args.url
username = args.username
error_msg = args.error
max_workers = args.threads
password_file = args.passwords

# Validate URL
if not url.startswith('http'):
url = 'https://' + url

info(f"Starting automated attack on {url}")
info(f"Using {max_workers} concurrent threads")

# Auto-detect unless overridden (simplified for this version)
section("CONFIGURATION")
analysis = {
'login_mode': 'form',
'api_endpoint': url,
'username_field': args.username_field or 'email',
'password_field': args.password_field or 'password',
'csrf_token': None,
'csrf_value': None,
}
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--api-endpoint is documented as an override, but it is never applied: run_attack_automated always sets analysis['api_endpoint'] to url and does not use args.api_endpoint. This makes the CLI flag ineffective and prevents JSON API mode from targeting the correct endpoint unless the login URL itself is the API endpoint.

Copilot uses AI. Check for mistakes.
Comment on lines +555 to 568
section("STEP 2 - REVIEW & ADJUST")

# ── Confirm / override ──
section("STEP 2 — REVIEW & ADJUST")
print()
dim("Press Enter to accept the auto-detected value, or type a new one.")
print()
analysis = {
'login_mode': 'form',
'api_endpoint': url,
'username_field': 'email',
'password_field': 'password',
'csrf_token': None,
'csrf_value': None,
}

analysis['username_field'] = prompt("Username field name", default=analysis['username_field'],
hint="The form field name for the username/email input")
analysis['username_field'] = prompt("Username field name", default=analysis['username_field'])
analysis['password_field'] = prompt("Password field name", default=analysis['password_field'])

Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interactive mode no longer offers a way to select JSON API mode or provide an API endpoint (and it also no longer performs the README-described auto-detection). analysis is hard-coded to login_mode: 'form' and api_endpoint: url, which effectively disables JSON API support for interactive users.

Copilot uses AI. Check for mistakes.
Comment on lines 8 to +12
- JSON API login (modern SPA/React/Vue/Angular sites)
- Universal CSRF bypass (hidden inputs, meta tags, cookies, headers)
- Auto-detection of login type, field names, and API endpoints
- Multi-threaded with progress bar
- Color-coded terminal output
- Beautiful Rich-styled terminal output with hacker theme
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README still states the tool auto-detects login type/fields/API endpoint and shows prompts for API endpoint + login mode selection, but the updated bruteforce.py no longer performs auto-detection and interactive mode is hard-coded to login_mode='form' without asking for an API endpoint. Please update the README to match current behavior (or restore the removed auto-detection / mode selection).

Copilot uses AI. Check for mistakes.
Comment on lines +451 to +488
parser.add_argument('--threads', '-t', type=int, default=10,
help='Number of concurrent worker threads (default: 10)')

# Optional field customization
parser.add_argument('--username-field', type=str, help='Override auto-detected username field name')
parser.add_argument('--password-field', type=str, help='Override auto-detected password field name')
parser.add_argument('--api-endpoint', type=str, help='Override auto-detected API endpoint (for JSON API mode)')
parser.add_argument('--login-mode', choices=['form', 'api'], help='Force login mode instead of auto-detecting')

return parser.parse_args()


def main():
# Parse arguments FIRST before showing banner
args = parse_arguments()

# Show banner only for interactive mode or first automated call
banner()

section("STEP 1 — TARGET INFO")
print()

# Check if running in automated mode or interactive mode
if args.url and args.username and args.error:
# Automated mode - run with provided arguments (banner already shown)
run_attack_automated(args, show_banner=False)
else:
# Interactive mode - prompt user for input (banner already shown)
run_attack_interactive(show_banner=False)


def run_attack_automated(args, show_banner=True):
"""Run attack in fully automated mode using command-line arguments."""
if show_banner:
banner()

url = args.url
username = args.username
error_msg = args.error
max_workers = args.threads
password_file = args.passwords
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In automated/CLI mode, --threads is used directly as max_workers without validation. Passing 0 or a negative value will raise at ThreadPoolExecutor(max_workers=...). Please validate/coerce args.threads (similar to interactive mode) before starting the attack.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants