T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/deploy_m1.py:64- Finding
Unauthenticated Network Endpoint Executes Claude with Permission Checks Disabled
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is a real remote Claude Code dispatcher, but it deploys unauthenticated remote execution paths with permission checks disabled.
Review before installing. Only use this on trusted private networks and trusted hosts after adding authentication for FastAPI and Redis, removing Claude permission bypass, disabling shell-based prompt execution, restoring SSH host-key verification, and defining stop/uninstall procedures for the background services.
scripts/deploy_m1.py:64Unauthenticated Network Endpoint Executes Claude with Permission Checks Disabled
scripts/exec.py:109Unauthenticated and Unencrypted Redis Queue Allows Task Injection and Result Tampering
scripts/exec.py:158Shell Injection in the SSH Screen Fallback
scripts/exec.py:148SSH Host-Key Verification Is Disabled
scripts/deploy_m1.py:46Unpinned Packages Are Installed into the Remote Python Environment
scripts/deploy_m1.py:185Deployment Leaves Background Execution Services Active and Modifies the Remote Shell Profile
A second description-behavior mismatch indicates the skill may edit SSH configuration, set up connection pooling, alter shell initialization files, and perform direct SSH-based host configuration despite being presented as a three-channel task dispatcher. Hidden host reconfiguration and shell-init changes materially increase persistence and control on remote machines beyond what a user would expect from the description.
A second description-behavior mismatch indicates the skill may edit SSH configuration, set up connection pooling, alter shell initialization files, and perform direct SSH-based host configuration despite being presented as a three-channel task dispatcher. Hidden host reconfiguration and shell-init changes materially increase persistence and control on remote machines beyond what a user would expect from the description.
The deployed worker invokes Claude with --permission-mode bypassPermissions, explicitly disabling normal safeguards for a remote task executor. Combined with Redis-delivered prompts, this gives anyone who can enqueue tasks a powerful remote code execution pathway on the target machine with reduced guardrails.
Beyond being a risky configuration choice, enabling bypassed permissions in a generated worker without strong warning or safety gates makes dangerous execution easy to deploy accidentally. Because this skill is expressly for dispatching commands to a remote Claude instance, suppressed safeguards materially increase the chance of misuse and system compromise.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Host m1
HostName 你的远程机器IP
User m1-meng
IdentityFile ~/.ssh/id_rsa
# 保活:每10秒发送心跳,断3次则断开
ServerAliveInterval 10
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Host m1
HostName 你的远程机器IP
User m1-meng
IdentityFile ~/.ssh/id_rsa
# 保活:每10秒发送心跳,断3次则断开
ServerAliveInterval 10
The ProxyJump configuration routes through root@... while also assuming a reusable private key, which materially increases credential and trust exposure compared with a non-root bastion account. Even without key exfiltration, normalizing root as the transit user expands blast radius if that hop is compromised or misused.
HostName 你的远程机器IP
User m1-meng
ProxyJump root@你的中转机器IP
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 10
ServerAliveCountMax 3
ControlMaster auto
Allowing arbitrary string commands to flow into subprocess.run with shell=True is a classic command-injection sink. Within an agent skill intended to dispatch remote actions, this pattern is especially sensitive because upstream prompts, tool outputs, or config values may eventually influence the executed string.
print(f" {msg}", flush=True)
def run(cmd, capture=True):
r = subprocess.run(cmd, shell=True, capture_output=capture, text=True, timeout=30)
return r.returncode, r.stdout, r.stderr
def ssh_cmd(host, cmd, timeout=30):
The function combines unvalidated host and command text into a shell-invoked SSH command, enabling parameter abuse through shell metacharacters or crafted SSH arguments. This can result in execution of unintended local commands, malicious remote payloads, or option injection that changes trust behavior such as proxying or key usage.
def ssh_cmd(host, cmd, timeout=30):
full_cmd = f'ssh -o "ServerAliveInterval=10" -o "ServerAliveCountMax=3" -o "ConnectTimeout=10" {host} "source ~/.zshrc && {cmd}"'
r = subprocess.run(full_cmd, shell=True, capture_output=True, text=True, timeout=timeout)
return r.returncode, r.stdout, r.stderr
def main():
The same payload also appends raw SSH configuration text into a remote config file, so any future introduction of dynamic values into SSH_CONFIG, SSH_DIR, or CONFIG_FILE would become a direct remote command/config injection vector. In a skill already centered on remote execution, hidden configuration-writing sinks materially raise risk.
# 写入新配置
code, out, err = ssh_cmd(HOST, f'''
mkdir -p {SSH_DIR}
chmod 700 {SSH_DIR}
cat > {CONFIG_FILE}.new << 'SSHEOF'
{SSH_CONFIG}
SSHEOF
The same payload also appends raw SSH configuration text into a remote config file, so any future introduction of dynamic values into SSH_CONFIG, SSH_DIR, or CONFIG_FILE would become a direct remote command/config injection vector. In a skill already centered on remote execution, hidden configuration-writing sinks materially raise risk.
# 写入新配置
code, out, err = ssh_cmd(HOST, f'''
mkdir -p {SSH_DIR}
chmod 700 {SSH_DIR}
cat > {CONFIG_FILE}.new << 'SSHEOF'
{SSH_CONFIG}
SSHEOF
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
print()
print("手动清理连接池:")
print(" ssh -O exit m1 # 关闭控制连接")
print(" rm /tmp/ssh_mux_* # 清除残留 socket")
if __name__ == "__main__":
main()
The code claims to be a Claude Code remote executor, but one branch executes the prompt as a raw shell command. This violates least surprise and materially increases risk because callers expecting prompt dispatch may unknowingly trigger arbitrary command execution on a remote machine.
The screen fallback does not dispatch instructions to Claude Code; it directly runs the provided prompt as a shell command on the remote host. In the context of a skill advertised as remote Claude Code execution, this semantic mismatch is especially dangerous because users may supply natural-language instructions that are unexpectedly treated as executable shell input.
This path executes user-provided prompt text directly on a remote shell with no confirmation, guardrails, or safety warning. Given the skill context, that means a normal-language instruction can become arbitrary code execution on another machine, which is a severe integrity and availability risk.
Using subprocess.run(..., shell=True) with a command string that incorporates user-controlled prompt data is a classic tool-parameter abuse pattern. In this skill's context, it enables arbitrary remote shell execution and undermines the claimed purpose of merely forwarding instructions to Claude Code.
f"ssh -o ServerAliveInterval=30 -o StrictHostKeyChecking=no {SSH_HOST} "
f"'screen -dmS {screen_name} /bin/zsh -c \"{escaped_prompt}\"'"
)
r = subprocess.run(ssh_cmd, shell=True, capture_output=True, timeout=15)
return r.returncode == 0
except Exception:
return False
The skill exposes capabilities for network, shell, environment access, and file writes, yet declares no explicit tool scope or permission boundaries. For a skill centered on remote command dispatch, this omission is dangerous because it leaves a high-risk execution surface unconstrained and makes accidental or unauthorized remote actions more likely.
The trigger phrases are broad enough to activate on generic requests like asking to 'dispatch to Claude Code' or 'remote execute,' which increases the chance of unintended invocation. In a skill that can reach remote machines and issue commands, overbroad activation materially raises the risk of accidental high-impact actions.
The documentation normalizes multiple remote execution paths, deployment steps, and process management operations without clear safety constraints, approval requirements, or warnings about trust boundaries. In context, this makes the skill more dangerous because it encourages direct remote code execution workflows without emphasizing authentication, authorization, command validation, or blast-radius control.
The documented use of nohup to start a long-running worker in the background establishes persistent execution on the remote machine. While this may be operationally intended, persistence is security-relevant because it creates unattended code execution that can continue processing tasks after the initiating session ends.
pip3 install redis uvicorn fastapi
# 启动 Worker(后台常驻)
nohup python3 cc_worker.py > worker.log 2>&1 &
# 启动 API
nohup python3 cc_api.py > api.log 2>&1 &
The API is also launched via nohup as a detached background process, creating a persistent remote service that may remain exposed on the network. Without clear access control and lifecycle management, this increases the risk of unauthorized use, forgotten exposure, and harder-to-audit execution paths.
nohup python3 cc_worker.py > worker.log 2>&1 &
nohup python3 cc_api.py > api.log 2>&1 &
## 三通道(按优先级)
The restart command kills and relaunches the worker remotely in the background, reinforcing persistence and allowing remote process lifecycle control over command-executing components. In this skill's context, the ability to re-establish a task-processing daemon remotely increases operational control and potential abuse if the skill is misused or triggered unexpectedly.
ssh 远程机器 "ps aux | grep cc_"
# 重启 Worker
ssh 远程机器 "pkill -f cc_worker; nohup python3 ~/cc_worker.py > ~/worker.log 2>&1 &"
# 重启 API
ssh 远程机器 "pkill -f cc_api; nohup python3 ~/cc_api.py > ~/api.log 2>&1 &"
The remote API restart command similarly re-establishes a persistent network-facing service, which can restore remote execution capability after interruption. In a remote-dispatch skill, this materially increases the ability to maintain continued access and service availability without strong governance.
ssh 远程机器 "pkill -f cc_worker; nohup python3 ~/cc_worker.py > ~/worker.log 2>&1 &"
ssh 远程机器 "pkill -f cc_api; nohup python3 ~/cc_api.py > ~/api.log 2>&1 &"
## 故障排查
The ssh helper interpolates an arbitrary command string into a remote shell invocation (source ~/.zshrc && {cmd}), which creates a command-injection sink if any caller ever passes untrusted input. In this script the current call sites are mostly hardcoded, but the helper is generic and the skill’s purpose is remote execution, which makes this pattern especially dangerous in context.
HOST = SSH_HOST
def ssh(cmd, timeout=30):
r = subprocess.run(
["ssh", "-o", "ServerAliveInterval=10", HOST, f"source ~/.zshrc && {cmd}"],
capture_output=True, text=True, timeout=timeout
)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
return r.returncode, r.stdout, r.stderr
def scp(local, remote):
r = subprocess.run(["scp", "-o", "ServerAliveInterval=10", local, f"{HOST}:{remote}"],
capture_output=True, timeout=30)
return r.returncode
No suspicious patterns detected.