feat: support scanning IP addresses
This commit is contained in:
@@ -18,13 +18,14 @@ class StrixAgent(BaseAgent):
|
||||
|
||||
super().__init__(config)
|
||||
|
||||
async def execute_scan(self, scan_config: dict[str, Any]) -> dict[str, Any]:
|
||||
async def execute_scan(self, scan_config: dict[str, Any]) -> dict[str, Any]: # noqa: PLR0912
|
||||
user_instructions = scan_config.get("user_instructions", "")
|
||||
targets = scan_config.get("targets", [])
|
||||
|
||||
repositories = []
|
||||
local_code = []
|
||||
urls = []
|
||||
ip_addresses = []
|
||||
|
||||
for target in targets:
|
||||
target_type = target["type"]
|
||||
@@ -53,6 +54,8 @@ class StrixAgent(BaseAgent):
|
||||
|
||||
elif target_type == "web_application":
|
||||
urls.append(details["target_url"])
|
||||
elif target_type == "ip_address":
|
||||
ip_addresses.append(details["target_ip"])
|
||||
|
||||
task_parts = []
|
||||
|
||||
@@ -74,6 +77,10 @@ class StrixAgent(BaseAgent):
|
||||
task_parts.append("\n\nURLs:")
|
||||
task_parts.extend(f"- {url}" for url in urls)
|
||||
|
||||
if ip_addresses:
|
||||
task_parts.append("\n\nIP Addresses:")
|
||||
task_parts.extend(f"- {ip}" for ip in ip_addresses)
|
||||
|
||||
task_description = " ".join(task_parts)
|
||||
|
||||
if user_instructions:
|
||||
|
||||
@@ -260,6 +260,9 @@ Examples:
|
||||
# Domain penetration test
|
||||
strix --target example.com
|
||||
|
||||
# IP address penetration test
|
||||
strix --target 192.168.1.42
|
||||
|
||||
# Multiple targets (e.g., white-box testing with source and deployed app)
|
||||
strix --target https://github.com/user/repo --target https://example.com
|
||||
strix --target ./my-project --target https://staging.example.com --target https://prod.example.com
|
||||
@@ -275,7 +278,7 @@ Examples:
|
||||
type=str,
|
||||
required=True,
|
||||
action="append",
|
||||
help="Target to test (URL, repository, local directory path, or domain name). "
|
||||
help="Target to test (URL, repository, local directory path, domain name, or IP address). "
|
||||
"Can be specified multiple times for multi-target scans.",
|
||||
)
|
||||
parser.add_argument(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import ipaddress
|
||||
import re
|
||||
import secrets
|
||||
import shutil
|
||||
@@ -141,7 +142,7 @@ def generate_run_name() -> str:
|
||||
|
||||
|
||||
# Target processing utilities
|
||||
def infer_target_type(target: str) -> tuple[str, dict[str, str]]:
|
||||
def infer_target_type(target: str) -> tuple[str, dict[str, str]]: # noqa: PLR0911
|
||||
if not target or not isinstance(target, str):
|
||||
raise ValueError("Target must be a non-empty string")
|
||||
|
||||
@@ -167,6 +168,13 @@ def infer_target_type(target: str) -> tuple[str, dict[str, str]]:
|
||||
return "repository", {"target_repo": target}
|
||||
return "web_application", {"target_url": target}
|
||||
|
||||
try:
|
||||
ip_obj = ipaddress.ip_address(target)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
return "ip_address", {"target_ip": str(ip_obj)}
|
||||
|
||||
path = Path(target).expanduser()
|
||||
try:
|
||||
if path.exists():
|
||||
@@ -191,7 +199,8 @@ def infer_target_type(target: str) -> tuple[str, dict[str, str]]:
|
||||
"- A valid URL (http:// or https://)\n"
|
||||
"- A Git repository URL (https://github.com/... or git@github.com:...)\n"
|
||||
"- A local directory path\n"
|
||||
"- A domain name (e.g., example.com)"
|
||||
"- A domain name (e.g., example.com)\n"
|
||||
"- An IP address (e.g., 192.168.1.10)"
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user