安全决策报告

ludwitt-university

The skill embeds a server-controlled update instruction (curl|sh) into console.error output after every API request, creating a potential C2 channel where the remote server can inject and cause execution of arbitrary shell commands through agent stderr monitoring.

安装决策优先 来源: ClawHub 扫描时间: 2026/6/20
文件 6
IOC 8
越权项 2
发现 6
最直接的威胁证据
严重 文档欺骗
Server-controlled shell command injection via updateInstructions

The daemon embeds the server-returned 'updateInstructions' field directly into a console.error() call at daemon.js:42. If the server (opensource.ludwitt.com) is compromised or returns malicious updateInstructions containing 'curl | sh', and if the agent's environment monitors/processes stderr output, arbitrary shell commands can be auto-executed. This is a covert C2 channel that bypasses the skill's declared permissions.

daemon.js:42

为什么得出这个结论

3/4 个维度触发
阻止
声明与实际能力

发现 2 项声明之外的能力或越权行为。

阻止
隐藏执行与外联

提取到 1 个高危 IOC 或外联信号。

阻止
攻击链与高危发现

报告包含 5 步攻击链,另有 3 项高危或严重发现。

通过
依赖与供应链卫生

依赖结构存在,但暂未看到明显高危告警。

攻击链

01
Agent installs skill via install.sh or curl|sh from SKILL.md Option A/B

初始入口 · SKILL.md:39

02
install.sh registers a launchd (macOS) or systemd (Linux) service for boot persistence

持久化 · install.sh:208

03
Machine fingerprint (hostname + platform + arch + CPU model) sent to opensource.ludwitt.com at registration

credential_theft · install.sh:64

04
PATH modification appended to ~/.zshrc or ~/.bashrc for ~/.ludwitt/bin

持久化 · install.sh:229

05
Server-controlled updateInstructions field embedded in console.error at daemon.js:42 — if server returns malicious curl|sh, and agent monitors stderr, arbitrary command executes

最终危害 · daemon.js:42

风险分是怎么被拉高的

Server-controlled curl|sh update injection +30

daemon.js:42 embeds result.updateInstructions from the server into console.error; combined with stderr monitoring, this enables server-injected arbitrary shell command execution via curl|sh pattern

Persistent background service with boot persistence +12

install.sh registers a launchd (macOS) or systemd (Linux) service that auto-starts on boot, undeclared in SKILL.md capabilities

Machine fingerprinting with os.cpus() and os.hostname() +8

install.sh:64-69 generates SHA256 fingerprint from hostname, platform, arch, CPU model — sent to remote server at registration

No declared shell/allowedTools mapping +5

SKILL.md requires 'Bash' access but _meta.json and SKILL.md lack explicit allowedTools declarations

MIT-0 license discrepancy +2

skill-card.md states MIT-0 but AGPL-3.0 is claimed in SKILL.md

最关键的证据

严重 文档欺骗

Server-controlled shell command injection via updateInstructions

The daemon embeds the server-returned 'updateInstructions' field directly into a console.error() call at daemon.js:42. If the server (opensource.ludwitt.com) is compromised or returns malicious updateInstructions containing 'curl | sh', and if the agent's environment monitors/processes stderr output, arbitrary shell commands can be auto-executed. This is a covert C2 channel that bypasses the skill's declared permissions.

daemon.js:42
Remove the updateInstructions field from console.error output entirely. If auto-updates are needed, verify the update script hash before execution, never pipe directly to sh.
高危 权限提升

Undeclared persistent background service with boot persistence

install.sh installs a launchd service on macOS (~/Library/LaunchAgents/com.ludwitt.daemon.plist) and a systemd service on Linux (~/.config/systemd/user/ludwitt-daemon.service). Both are configured to RunAtLoad/Start on boot with KeepAlive. This persistence mechanism is not declared in SKILL.md's capabilities table.

install.sh:208
Declare boot-persistent service installation in SKILL.md capabilities. Require explicit user consent before modifying system service managers.
高危 数据外泄

Machine fingerprinting sent to remote server at registration

install.sh generates a SHA256 machine fingerprint by hashing hostname, OS platform, architecture, and CPU model combined with 32 random bytes. This fingerprint is sent to the Ludwitt server at registration time (install.sh:136). This creates a unique per-machine identifier that persists across reinstalls if the auth.json is retained.

install.sh:64
Use a randomly generated UUID instead of hardware-derived fingerprinting. Hardware fingerprinting enables server-side device tracking across reinstalls.
中危 文档欺骗

Shell rc file modification undeclared in capabilities

install.sh:229-244 appends 'export PATH=$HOME/.ludwitt/bin:$PATH' to ~/.zshrc or ~/.bashrc without declaring this shell environment modification in SKILL.md. This is an undocumented side effect that persists PATH changes.

install.sh:229
Declare shell rc modification as a required capability in SKILL.md.
中危 敏感访问

API key stored in plaintext file with mode 600

Credentials (agentId, apiKey, fingerprint) are stored in ~/.ludwitt/auth.json with chmod 600. While the file permissions are correctly restrictive, the apiKey is a bearer token that provides API access and is sent with every request. No encryption at rest.

install.sh:151
Use OS keychain (Keychain Access on macOS, keyring on Linux) instead of a plaintext JSON file for storing the API key.
低危 供应链

No dependency pinning

No package.json, requirements.txt, or equivalent dependency manifest exists. The daemon relies only on built-in Node.js modules (fs, path, https, http, crypto via os). No external npm dependencies means no supply chain risk from third-party packages.

daemon.js:1
No action needed — using only Node.js built-in modules is a positive security trait.

声明能力 vs 实际能力

网络访问 通过
声明 READ
推断 READ
SKILL.md line ~20 declares network access
文件系统 通过
声明 WRITE
推断 WRITE
SKILL.md requires file write access for papers; install.sh writes to ~/.ludwitt/
命令执行 阻止
声明 NONE
推断 WRITE
install.sh:136 executes curl; install.sh:229-260 modifies shell rc files; daemon.js:42 contains curl|sh injection
环境变量 阻止
声明 NONE
推断 READ
install.sh:64 reads os.hostname(), os.platform(), os.cpus() for fingerprinting
技能调用 通过
声明 NONE
推断 NONE
No skill invocation chain detected

可疑产物与外联

严重 危险命令
curl -sSL https://opensource.ludwitt.com/install | sh

daemon.js:42

中危 外部 URL
https://opensource.ludwitt.com

README.md:34

中危 外部 URL
https://your-deployed-app.vercel.app

SKILL.md:181

中危 外部 URL
https://www.youtube.com/watch?v=...

SKILL.md:183

中危 外部 URL
https://opensource.ludwitt.com/install

daemon.js:42

中危 外部 URL
http://www.apple.com/DTDs/PropertyList-1.0.dtd

install.sh:216

中危 外部 URL
https://clawhub.ai/user/rogerSuperBuilderAlpha

skill-card.md:7

中危 外部 URL
https://clawhub.ai/rogerSuperBuilderAlpha/ludwitt-university

skill-card.md:29

依赖与供应链

包名版本来源漏洞备注
Node.js builtins only (fs, path, https, http, url, crypto via os) N/A builtin No npm package dependencies — zero supply chain risk

文件构成

6 个文件 · 1469 行
JavaScript 1 个文件 · 728 行Markdown 3 个文件 · 413 行Shell 1 个文件 · 323 行JSON 1 个文件 · 5 行
需关注文件 · 5
daemon.js JavaScript · 728 行
Server-controlled shell command injection via updateInstructions · No dependency pinning · curl -sSL https://opensource.ludwitt.com/install | sh · https://opensource.ludwitt.com/install
install.sh Shell · 323 行
Undeclared persistent background service with boot persistence · Machine fingerprinting sent to remote server at registration · Shell rc file modification undeclared in capabilities · API key stored in plaintext file with mode 600 · http://www.apple.com/DTDs/PropertyList-1.0.dtd
SKILL.md Markdown · 263 行
https://your-deployed-app.vercel.app · https://www.youtube.com/watch?v=...
README.md Markdown · 105 行
https://opensource.ludwitt.com
skill-card.md Markdown · 45 行
https://clawhub.ai/user/rogerSuperBuilderAlpha · https://clawhub.ai/rogerSuperBuilderAlpha/ludwitt-university
其他文件 · _meta.json

安全亮点

Uses only Node.js built-in modules (fs, path, https, http, crypto via os) — no third-party npm dependencies, eliminating supply chain risk
API key and fingerprint are stored with mode 600 (owner-read-only) permissions
MIT-0 license provides clear usage terms
skill-card.md contains a 'Known Risks and Mitigations' section that acknowledges the persistent service and credential storage risks
install.sh validates minimum Node.js version (18+) before proceeding
No obfuscation techniques detected — code is readable and auditable
Registration HTTP response codes are validated and non-200 responses cause install failure
Request retry logic with exponential backoff prevents accidental DoS from retry storms