T03 · Remote Payload Retrieval and Execution
- Location
SKILL.md:43- Finding
Unverified Remote Script Executed Directly Through Bash
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This appears to be a real monitoring agent, but its installer, credential handling, transport security, and persistence controls are too risky for automatic trust.
Review this carefully before installing, especially on production servers. Require a verified release or package, remove curl-to-bash installation, restore normal TLS validation, protect and rotate API credentials, and provide a clear uninstall path for cron jobs before trusting it.
SKILL.md:43Unverified Remote Script Executed Directly Through Bash
src/agent_client.py:158TLS Certificate and Hostname Verification Disabled for Sensitive Telemetry
src/agent_client.py:181Persistent Scheduled Execution Installed Through User Crontab
The agent sends sensitive host inventory and credentials over HTTPS with certificate validation explicitly disabled (check_hostname=False, CERT_NONE). Because the destination URL is environment/config-controlled, an attacker on the network or controlling DNS/proxying can intercept traffic, steal the API key, and receive detailed system telemetry intended for the cloud service.
ctx.verify_mode = ssl.CERT_NONE
try:
with urllib.request.urlopen(req, context=ctx, timeout=30) as resp:
return resp.status == 200
except urllib.error.HTTPError as e:
print(f"API error: {e.code} {e.reason}", file=sys.stderr)
The document markets the skill as AI-powered, real-time, and auto-remediating, while the described behavior is periodic reporting, remote cloud analysis, and installation/configuration steps with sensitive host access. This overstatement can mislead operators into trusting the system's capabilities and safety model, causing risky deployment decisions or overbroad access based on inaccurate expectations.
The finding spans into the install flow that fetches and executes a remote installer/script, which is a classic external-script-fetching risk. Because the skill is for infrastructure monitoring and encourages host-level installation plus recurring execution, a compromised distribution path could grant persistent code execution across production systems.
curl -X POST https://api.agentpulse.io/v1/servers \
-H "Content-Type: application/json" \
-d '{"hostname": "my-server", "plan": "starter"}'
The skill instructs users to perform network operations, download/install software, write files under privileged paths, and schedule recurring execution, but it does not declare any tool scope or permissions. That mismatch reduces transparency and informed consent, making it easier for a user or agent to trigger sensitive actions without clear up-front disclosure.
The skill states that the agent ships server metrics to a cloud API and that the provider stores history and performs analysis, but it does not clearly warn about ongoing external data transmission or the types of operational metadata that may leave the host. In an infrastructure-monitoring context, this can disclose sensitive topology, service, process, and availability information to a third party.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
curl -X POST https://api.agentpulse.io/v1/servers \
-H "Content-Type: application/json" \
-d '{"hostname": "my-server", "plan": "starter"}'
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
curl -X POST https://api.agentpulse.io/v1/servers \
-H "Content-Type: application/json" \
-d '{"hostname": "my-server", "plan": "starter"}'
Piping a remote script directly into bash executes whatever the server returns at install time with the caller's privileges, eliminating an inspection step and creating a high-risk supply-chain path. In this context the command is part of the primary install flow for infrastructure software, so compromise of the site, CDN, DNS, or TLS trust chain could immediately lead to host takeover.
The manual installation instructions place an executable in /usr/local/bin and write API credentials to /etc/agentpulse.conf without warning about privileged system modification or secret handling. This can expose credentials through weak file permissions, backups, shell history, or multi-user access, while also normalizing root-level changes without informed consent.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"""Check if a systemd service is active."""
resolved = SERVICE_ALIASES.get(name, name)
try:
result = subprocess.run(
["systemctl", "is-active", resolved],
capture_output=True, text=True, timeout=5
)
The manifest emphasizes infrastructure monitoring with real-time alerts and baseline learning, which justifies collecting health metrics. However, collecting listening ports via ss -tlnp and process counts materially increases system inventory/reconnaissance capability and is not clearly justified by the stated purpose in this manifest text.
Full reports transmit detailed system and network inventory, including listening ports and process counts, without a clear warning or confirmation at runtime. In this skill context, the danger is amplified because the same data is sent over a TLS channel with verification disabled, increasing the risk of unintended disclosure to an attacker.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# Listening ports
ports = set()
try:
result = subprocess.run(
["ss", "-tlnp"], capture_output=True, text=True, timeout=10
)
for line in result.stdout.splitlines()[1:]:
This monitoring agent also installs recurring cron jobs, creating local persistence and modifying system scheduling beyond passive observation. In skill context, that makes the behavior more dangerous because users may expect telemetry collection but not enduring scheduler changes, especially when full reports include detailed host inventory.
The install path modifies the user's crontab immediately, without any confirmation prompt, dry run, or rollback mechanism. This creates persistence and can silently alter host behavior in a way users may not anticipate from a monitoring agent, making it materially riskier in deployment environments.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
f"0 8 * * * {sys.executable} {agent_path} --full",
]
try:
result = subprocess.run(["crontab", "-l"], capture_output=True, text=True)
existing = result.stdout if result.returncode == 0 else ""
lines = [l for l in existing.splitlines() if "agentpulse" not in l.lower() and l.strip()]
lines.extend(entries)
While the subprocess call itself is not shell-injection prone, it writes a new crontab entry using sys.executable and __file__ without escaping or validating those values. If the agent resides in a path containing spaces or cron metacharacters, the installed cron line can execute unexpectedly or fail, and the function also alters persistence without additional safeguards.
lines = [l for l in existing.splitlines() if "agentpulse" not in l.lower() and l.strip()]
lines.extend(entries)
new_cron = "\n".join(lines) + "\n"
proc = subprocess.run(["crontab", "-"], input=new_cron, text=True)
if proc.returncode == 0:
print("Cron entries installed successfully.")
else:
The top-level docstring presents the program as an agent that reports system metrics to the cloud API and shows usage including installation, but it does not communicate that installation rewrites the current crontab. This documentation understates a meaningful side effect and gives a narrower impression than the code's actual behavior.