在日常运维和开发中,Shell脚本常包含敏感信息(如数据库密码、API密钥、服务器IP等)。若直接分发脚本,源码暴露风险极高。此时,加密脚本(可执行但不可读)成为刚需。常见的 shc
工具可将脚本编译为二进制文件,实现“能执行但不可看”的效果。
安装shc
# Ubuntu/Debian
sudo apt install shc
# CentOS/RHEL
sudo yum install epel-release && sudo yum install shc
wget http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.9.tgz
tar xvfz shc-3.8.9.tgz && cd shc-3.8.9
make && sudo make install
加密脚本
基础命令格式:
shc -f your_script.sh # 生成 your_script.sh.x(二进制)和 your_script.sh.x.c(C源码)
-r
:放宽安全限制,允许跨系统运行(解决环境兼容性问题)。-e DD/MM/YYYY
:设置过期时间,超时拒绝执行。-m "message"
:自定义过期提示信息。shc -v -r -f your_script.sh -o encrypted_script
运行加密后的脚本
./your_script.sh.x # 直接执行二进制文件
这里 .x 文件若执行正常,那最好不过了,若执行时却无响应、无输出、无报错,请看下一步。
使用 shc
加密脚本后,执行时却无响应、无输出、无报错,只能强制终止(Ctrl+C
)。例如:
shc -f your_script.sh # 加密
./your_script.sh.x # 执行卡死!
动态链接依赖问题
shc
默认生成动态链接的可执行文件,依赖系统的 glibc
等共享库。若目标机器的库版本与编译环境不一致(如 libc.so.6
版本不匹配),程序会在加载阶段静默挂起。
因为要编译内核,这里曾经改过 libc 等一些库文件。
环境兼容性不足
即使使用 -r
参数(允许跨主机运行),仍可能因内核版本、动态加载器路径(如 /lib64/ld-linux-x86-64.so.2
)差异导致失败。
通过强制静态编译,将所有依赖库嵌入可执行文件,彻底消除运行时依赖:
CFLAGS="-static" shc -r -v -f your_script.sh
# -v 是打印详情
# -r 增加其他设备运行兼容性
生成 hello.sh.x
后直接执行即可:
./your_script.sh # 正常运行
这里本机能正常运行 ≠ 其他机,即使添加了
-r
参数
建议还是在运行脚本的设备上加密脚本。
特性 | 动态编译 | 静态编译(CFLAGS="-static" ) |
---|---|---|
依赖库处理 | 运行时加载系统的 .so 文件 |
库代码直接嵌入可执行文件 |
文件体积 | 较小(≈10–50KB) | 较大(≈1–5MB,含 libc 等库) |
环境兼容性 | 需匹配库版本,否则崩溃或卡死 | 独立运行,无视系统库版本 |
验证方法 | ldd your_script.sh.x 显示依赖的 .so |
file your_script.sh.x 显示 statically linked |
CFLAGS="-static"
:向 gcc
传递参数,强制静态链接所有库(如 libc
、libdl
)。-r
参数:放宽系统环境检查,允许二进制在不同主机间移植(仍需同架构操作系统)。-v
参数:输出编译日志,便于调试(如确认 -static
是否生效)。glibc
不兼容问题。文件体积膨胀
嵌入 libc
等库导致文件增大数十倍(可通过 strip your_script.sh.x
剥离调试符号减小 30% 体积)。
安全风险未根治
shc
加密本质是源码混淆(RC4 变体),密钥存储在二进制中,可通过内存 dump 或逆向工程破解。切勿用于高敏感场景!
工具 | 安全性 | 兼容性 | 适用场景 |
---|---|---|---|
shc |
中低 | 需静态 | 防 casual viewing |
gzexe |
低 | 极佳 | 快速隐藏(gzexe file.sh ) |
openssl |
高 | 依赖解密 | 需密钥管理的敏感脚本 |
strip --strip-all your_script.sh.x
,减少逆向线索。gcc-arm-linux-gnueabi
)。通过 CFLAGS="-static" shc -r -f script.sh
生成的静态二进制,完美解决了跨环境执行的卡死问题。但需注意: