Files
rpcscope/tests/test_runner.py
T
2026-10-15 12:34:26 -04:00

67 lines
3.0 KiB
Python

import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
from rpcscope.catalog import CHECKS
from rpcscope.runner import ScanConfig, _msf_command, _redacted, scan
class RunnerTests(unittest.TestCase):
def test_nonfinite_and_invalid_api_limits_are_rejected_before_collection(self):
for attribute, value in (("timeout", float("nan")), ("timeout", float("inf")),
("jobs", True), ("discovery_workers", 1.5),
("connect_timeout", float("nan")), ("connect_timeout", True)):
with self.subTest(attribute=attribute, value=value), patch("rpcscope.runner.doctor") as inspect:
config = ScanConfig(["192.0.2.1"])
setattr(config, attribute, value)
with self.assertRaises(ValueError):
scan(config)
inspect.assert_not_called()
def test_redacts_embedded_password(self):
command = ["rpcdump", "user:[email protected]"]
self.assertEqual(
_redacted(command, "supersecret"),
["rpcdump", "user:<redacted>@10.10.10.25"],
)
def test_dry_run_does_not_require_installed_collectors(self):
with tempfile.TemporaryDirectory() as directory:
config = ScanConfig(
targets=["10.10.10.0/24"],
username="",
password="",
shares=True,
dry_run=True,
out_dir=Path(directory),
)
self.assertEqual(scan(config), {})
self.assertEqual(config.commands[0][0:3], ["nxc", "smb", "10.10.10.0/24"])
def test_msf_escaped_credentials_are_never_recorded(self):
config = ScanConfig(targets=["192.0.2.1"], username="auditor", password='a\\b"c')
command = _msf_command("msfconsole", "192.0.2.1", config)
redacted = _redacted(command, config.password)
self.assertEqual(redacted[-1], "<redacted Metasploit resource script>")
self.assertNotIn(config.password, " ".join(redacted))
def test_discovery_interruption_retains_partial_hosts_and_skips_checks(self):
with tempfile.TemporaryDirectory() as temporary:
config = ScanConfig(["192.0.2.0/24"], out_dir=Path(temporary) / "out",
checks=[CHECKS["ms17-010"]])
tools = {"nxc": "nxc", "enum4linux-ng": None, "rpcdump": None, "msfconsole": None}
def interrupted(command, timeout, log, password, cancel):
cancel.set()
return 130, "SMB 192.0.2.1 445 HOST [*] Windows 11 (name:HOST) (domain:LAB)"
with patch("rpcscope.runner.doctor", return_value=tools), patch("rpcscope.runner._run", side_effect=interrupted) as run:
hosts = scan(config)
self.assertTrue(config.cancelled)
self.assertIn("192.0.2.1", hosts)
self.assertEqual(hosts["192.0.2.1"].checks["ms17-010"], "skipped-cancelled")
self.assertEqual(run.call_count, 1)
if __name__ == "__main__":
unittest.main()