Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a5f4fa6
Payload workbench
CommonHuman-Lab Aug 13, 2026
409fe06
package updates
CommonHuman-Lab Aug 13, 2026
b7fa44c
Update dependabot configuration to specify target branch
CommonHuman-Lab Aug 13, 2026
b066f47
Visual moved to toolspec
CommonHuman-Lab Aug 15, 2026
9363dfa
Migrate vuln intel to tool spec
CommonHuman-Lab Aug 15, 2026
4a27269
Session handover moved to tool spec
CommonHuman-Lab Aug 15, 2026
c2552fa
API audit moved to tool spec
CommonHuman-Lab Aug 15, 2026
30077de
http_framework moved to toolspec
CommonHuman-Lab Aug 15, 2026
7a07c5d
Add commonhuman-core dependency and update changelog for HTTP framewo…
CommonHuman-Lab Aug 15, 2026
dd7dcdd
Refactor HTTPTestingFramework to use HttpClient for session managemen…
CommonHuman-Lab Aug 15, 2026
164615d
uv locks
CommonHuman-Lab Aug 15, 2026
5236dc5
Enhance HTTP framework with new authentication tool
CommonHuman-Lab Aug 15, 2026
b408029
Add OpenAPI discovery tool and enhance API schema analyzer for better…
CommonHuman-Lab Aug 15, 2026
d6ddc9e
Add js_api_discover tool to extract REST/JSON API endpoints from SPA …
CommonHuman-Lab Aug 15, 2026
9d6151c
Add source_map_recover tool to recover original pre-minified JS sourc…
CommonHuman-Lab Aug 15, 2026
3954f4c
Add ws_discover and ws_inject tools for WebSocket endpoint discovery …
CommonHuman-Lab Aug 15, 2026
a2c3c96
Add dork_search tool for querying DuckDuckGo, Bing, and Yahoo for URL…
CommonHuman-Lab Aug 15, 2026
1953d18
Refactor of folder stucture
CommonHuman-Lab Aug 15, 2026
3d9a8a3
Enhance security and performance features
CommonHuman-Lab Aug 15, 2026
90b6709
Add boolean support to ParamField and update payload handling
CommonHuman-Lab Aug 15, 2026
26d9857
Update changelog to reflect boolean parameter rendering as toggle swi…
CommonHuman-Lab Aug 15, 2026
acbb7e4
Update README to reflect enhanced features and tool count
CommonHuman-Lab Aug 16, 2026
3434b56
Update README to simplify description of real-time dashboard feature
CommonHuman-Lab Aug 16, 2026
752cd89
feat: add decloak functionality to workbench
CommonHuman-Lab Aug 17, 2026
ee8f5c7
Workbench updates
CommonHuman-Lab Aug 17, 2026
a2b36cc
Workbench updates
CommonHuman-Lab Aug 17, 2026
866d6ff
Removed dependecy
CommonHuman-Lab Aug 19, 2026
b393b84
Update changelog for version 1.9.0 release date
CommonHuman-Lab Aug 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ updates:
directory: "/"
schedule:
interval: "weekly"
target-branch: "beta/next"
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# Changelog

## 1.9.0 (2026-08-20)

### Run page
- Boolean params (e.g. `exploit`, `dump_all`) now render as toggle switches instead of free-text true/false fields.

### Payload workbench
- New "Payload Workbench" — generate and test payloads (SQLi, XSS, etc.) without leaving the UI.

### HTTP framework
- `http_spider` now runs on the `commonhuman-core` crawler — threaded discovery, richer form parsing (select/hidden/required-field handling), and correct handling of redirects and off-origin filtering.
- New `http_authenticate` tool — logs the shared session into a target via form login, OAuth2 client-credentials, or Basic/Digest/NTLM, so subsequent `http_request`/`http_spider`/`http_intruder` calls run authenticated.
- New `js_api_discover` tool — extracts REST/JSON API endpoints straight out of a SPA's JavaScript bundles (React/Vue/Angular), catching `fetch`/`axios` calls a plain crawl never sees.
- New `source_map_recover` tool — recovers original pre-minified JS/TS source via `sourceMappingURL`/`.map` files, for real source instead of minified bundles when reviewing DOM-XSS sinks.
- New `ws_discover`/`ws_inject` tools — find WebSocket endpoints referenced in a page's HTML/JS, then send payloads over them and check responses for reflection (chat, real-time features).

### API scanning
- `api_schema_analyzer` now parses OpenAPI/Swagger specs (JSON or YAML, v2 or v3, `$ref`-resolving) via `commonhuman-core` instead of a bare JSON fetch — every endpoint comes back with a real, scannable URL (path params filled, base URL resolved) ready to hand to breachsql/phaseaccess.
- New `openapi_discover` tool — probes a target's common paths (`/openapi.json`, Swagger UI, ReDoc, ...) to locate its spec automatically.

### Recon
- New `dork_search` tool — queries DuckDuckGo/Bing/Yahoo for URLs matching a dork query (e.g. `site:target.com inurl:search`), returning only parameter-bearing candidates. No API keys required.

### Hardening
- Smart-scan now re-scores remaining tool candidates between small batches instead of committing to one fixed list up front, so a failure can down-rank a tool before the next round fires.
- Fixed a shared-driver race in the browser agent — concurrent requests now queue instead of racing on the same Selenium session.
- Harvested credentials are now encrypted at rest.
- Plugin loading now logs before executing third-party code, with an opt-in allowlist mode.

## 1.8.0 - exploitotter (2026-08-13)

### Workbench
Expand Down
24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

NyxStrike connects LLM agents to real offensive security tools and executes full attack chains — from recon to exploitation.

**200+ tools · 50+ categories · AI decision engine · Tamper-evident evidence chain**

---

## 🚀 Quick Start (Installation)
Expand Down Expand Up @@ -81,27 +83,29 @@ Connect NyxStrike to any MCP-compatible AI client — OpenCode, Cursor, Claude D

NyxStrike does not just run tools — it orchestrates full attack chains using AI decision-making.

- AI agents that chain tools automatically
- 185+ offensive security tools, all agent-controllable
- AI agents that chain tools automatically, guided by a decision engine that ranks and re-scores tools mid-scan
- 200+ offensive security tools, all agent-controllable
- Full attack workflow: recon → enumeration → exploitation → reporting
- Modular tool registry — add or remove tools without touching agent logic
- Local payload & data workbench — 40+ crypto, encoding, and analysis operations, no target required
- Every tool run hash-chained for tamper-evident, verifiable evidence
- Real-time dashboard — live output, network topology maps
- MCP-compatible — plug into any AI client you already use
- Real-time session dashboard with live command output and logs

> [Full feature breakdown](https://github.com/CommonHuman-Lab/nyxstrike/wiki/Features) · [Session & workbench docs](https://github.com/CommonHuman-Lab/nyxstrike/wiki/Dashboard-and-Sessions)

---

## 🧰 Tool Arsenal

185+ offensive security tools across 12 categories — all dynamically orchestrated by AI agents in real time.
200+ offensive security tools across 50+ categories — all dynamically orchestrated by AI agents in real time.

- Network reconnaissance
- Web exploitation
- Wireless security
- Network & wireless reconnaissance
- Web & API exploitation
- OSINT & intelligence gathering
- Password attacks
- Cloud & API security
- Password & credential attacks
- Binary exploitation & reverse engineering
- Cloud, container & IaC security
- Digital forensics & incident response

> [Full tool list by category](https://github.com/CommonHuman-Lab/nyxstrike/wiki/Tool-Arsenal)

Expand Down
10 changes: 4 additions & 6 deletions backend/server_api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from backend.server_api._generic.autoload import register_all_toolspec_blueprints
from .ai_assist import *
from .ai_payload import *
from .tools_catalog import *
from .ui_blueprint import *
from .settings import *
Expand All @@ -10,9 +9,9 @@
from .error_handling import *
from .ops import *
from .vuln_intel import *
from .web_framework import *
from .burp_agent import *
from .workbench import *
from .payload_workbench import *

def register_blueprints(app):
"""Register all API blueprints with the Flask app."""
Expand All @@ -33,7 +32,6 @@ def register_blueprints(app):
app.register_blueprint(api_topology_bp)

# OPS — General
app.register_blueprint(api_visual_bp)
app.register_blueprint(api_process_management_bp)
app.register_blueprint(api_process_execute_async_bp)
app.register_blueprint(api_process_get_task_result_bp)
Expand All @@ -47,9 +45,6 @@ def register_blueprints(app):
app.register_blueprint(api_process_scale_pool_bp)
app.register_blueprint(api_process_health_check_bp)

# Web Framework
app.register_blueprint(api_web_framework_http_framework_bp)

# Vulnerability Intelligence
app.register_blueprint(api_vulnerability_intelligence_bp)
app.register_blueprint(api_vuln_intel_cve_exploit_chain_bp)
Expand Down Expand Up @@ -96,3 +91,6 @@ def register_blueprints(app):

# Workbench
app.register_blueprint(api_workbench_bp)

# Payload Workbench
app.register_blueprint(api_payload_workbench_bp)
1 change: 0 additions & 1 deletion backend/server_api/ai_payload/__init__.py

This file was deleted.

1 change: 0 additions & 1 deletion backend/server_api/ops/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from .process_management import *
from .visual import *
from .system_monitoring import *
from .vulnerability_intelligence import *
from .logs import *
Expand Down
27 changes: 0 additions & 27 deletions backend/server_api/ops/system_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
import sys
import threading
import time
import traceback

import backend.server_core.config_core as config_core
from backend.server_core.command_executor import execute_command
from backend.server_core.modern_visual_engine import ModernVisualEngine

from backend.server_core.tool_constants import (
Expand Down Expand Up @@ -219,31 +217,6 @@ def ping():
})


@api_system_monitoring_bp.route("/api/command", methods=["POST"])
def generic_command():
"""Execute any command provided in the request with enhanced logging"""
try:
params = request.json
command = params.get("command", "")
use_cache = params.get("use_cache", True)
timeout = params.get("timeout")

if not command:
logger.warning("Command endpoint called without command parameter")
return jsonify({
"error": "Command parameter is required"
}), 400

result = execute_command(command, use_cache=use_cache, timeout=timeout)
return jsonify(result)
except Exception as e:
logger.error(f"Error in command endpoint: {str(e)}")
logger.error(traceback.format_exc())
return jsonify({
"error": f"Server error: {str(e)}"
}), 500


@api_system_monitoring_bp.route("/api/tools/categories", methods=["GET"])
def get_tool_categories():
"""Get the list of tool categories and their tools"""
Expand Down
32 changes: 0 additions & 32 deletions backend/server_api/ops/visual.py

This file was deleted.

91 changes: 63 additions & 28 deletions backend/server_api/ops/vulnerability_intelligence.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
from datetime import datetime
import json
import logging
import math
import time
import uuid
from typing import Optional
from werkzeug.local import LocalProxy

from backend.server_core.singletons import decision_engine, wordlist_store, enhanced_process_manager
Expand Down Expand Up @@ -159,16 +161,29 @@ def execute_tool_via_registered_endpoint(app, tool_name, params):
return body


def _run_smart_scan(target: str, objective: str, planner_mode, session_id, max_tools: int) -> dict:
"""Select and run optimal tools for a target in parallel, aggregating results.
def _run_smart_scan(
target: str,
objective: str,
planner_mode,
session_id,
max_tools: int,
batch_size: int = 3,
max_rounds: Optional[int] = None,
) -> dict:
"""Select and run optimal tools for a target in small concurrent batches,
re-scoring the remaining candidates against updated session/tool-stats
data between batches instead of committing to one fixed list up front.

Used by the decision_engine smart_scan/ai_reconnaissance_workflow/
ai_vulnerability_assessment tool handlers.
"""
profile = decision_engine.analyze_target(target)
selected_tools = decision_engine.select_optimal_tools(
profile, objective, planner_mode=planner_mode, session_id=session_id
)[:max_tools]

owns_session = not session_id
if owns_session:
session_id = create_session(
target=target, steps=[], source="smart_scan_iterative", objective=objective,
)["session_id"]

scan_results = {
"target": target,
Expand All @@ -188,18 +203,16 @@ def _run_smart_scan(target: str, objective: str, planner_mode, session_id, max_t
"combined_output": "",
}

if not selected_tools:
return scan_results

combined_output_parts = []
app = current_app._get_current_object() if isinstance(current_app, LocalProxy) else current_app

def execute_single_tool(tool_name, target, profile):
def execute_single_tool(tool_name, target, profile, session_id):
try:
logger.info(f"Executing {tool_name} with optimized parameters")

optimized_params = decision_engine.optimize_parameters(tool_name, profile)
optimized_params.setdefault("target", target)
optimized_params["session_id"] = session_id
result = execute_tool_via_registered_endpoint(app, tool_name, optimized_params)

vuln_count = 0
Expand Down Expand Up @@ -230,38 +243,60 @@ def execute_single_tool(tool_name, target, profile):
"success": False,
}

with ThreadPoolExecutor(max_workers=min(len(selected_tools), 5)) as executor:
future_to_tool = {
executor.submit(execute_single_tool, tool, target, profile): tool
for tool in selected_tools
}
executed_tools = set()
remaining = max_tools
rounds_cap = max_rounds or math.ceil(max_tools / batch_size)
round_num = 0

while remaining > 0 and round_num < rounds_cap:
round_num += 1
ranked = decision_engine.select_optimal_tools(
profile, objective, planner_mode=planner_mode, session_id=session_id
)
candidates = [t for t in ranked if t not in executed_tools]
if not candidates:
break
batch = candidates[: min(batch_size, remaining)]

with ThreadPoolExecutor(max_workers=len(batch)) as executor:
future_to_tool = {
executor.submit(execute_single_tool, tool, target, profile, session_id): tool
for tool in batch
}

for future in as_completed(future_to_tool):
tool_result = future.result()
scan_results["tools_executed"].append(tool_result)
for future in as_completed(future_to_tool):
tool_result = future.result()
scan_results["tools_executed"].append(tool_result)
executed_tools.add(tool_result["tool"])

if tool_result.get("vulnerabilities_found"):
scan_results["total_vulnerabilities"] += tool_result["vulnerabilities_found"]
if tool_result.get("vulnerabilities_found"):
scan_results["total_vulnerabilities"] += tool_result["vulnerabilities_found"]

if tool_result.get("stdout"):
combined_output_parts.append(f"\n=== {tool_result['tool'].upper()} OUTPUT ===\n")
combined_output_parts.append(tool_result["stdout"])
combined_output_parts.append("\n" + "=" * 50 + "\n")
if tool_result.get("stdout"):
combined_output_parts.append(f"\n=== {tool_result['tool'].upper()} OUTPUT ===\n")
combined_output_parts.append(tool_result["stdout"])
combined_output_parts.append("\n" + "=" * 50 + "\n")

remaining -= len(batch)

scan_results["combined_output"] = "".join(combined_output_parts)

successful_tools = [t for t in scan_results["tools_executed"] if t.get("success")]
failed_tools = [t for t in scan_results["tools_executed"] if not t.get("success")]
executed = scan_results["tools_executed"]
successful_tools = [t for t in executed if t.get("success")]
failed_tools = [t for t in executed if not t.get("success")]

scan_results["execution_summary"] = {
"total_tools": len(selected_tools),
"total_tools": len(executed),
"successful_tools": len(successful_tools),
"failed_tools": len(failed_tools),
"success_rate": len(successful_tools) / len(selected_tools) * 100 if selected_tools else 0,
"total_execution_time": sum(t.get("execution_time", 0) for t in scan_results["tools_executed"]),
"success_rate": len(successful_tools) / len(executed) * 100 if executed else 0,
"total_execution_time": sum(t.get("execution_time", 0) for t in executed),
"tools_used": [t["tool"] for t in successful_tools],
}

if owns_session:
scan_results["session_id"] = session_id

return scan_results


Expand Down
1 change: 1 addition & 0 deletions backend/server_api/payload_workbench/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .routes import *
Loading
Loading