#!/bin/bash # 攻击面 5:deploy.sh --prefix 沙箱模式会不会偷偷写到真实系统? # # 做法:造一组"假命令"垫在最前面(PATH 优先级最高), # 它们只把调用记录到日志,什么都不执行。 # 然后跑 deploy.sh --prefix /tmp/sbx,看: # a) 有没有调用 systemctl 去操作真实服务 # b) 有没有调用 iptables / ip link / sysctl 改真实系统 # c) 有没有往 /tmp/sbx 以外的地方写文件 # # 这样即使脚本里真有漏洞,也不会真的动到设备上的服务。 set -u SHIM=/tmp/sbxim SBX=/tmp/sbxroot LOG=$SHIM/calls.log SCRIPT=${1:-/root/dep/relay/deploy.sh} rm -rf "$SHIM" "$SBX" mkdir -p "$SHIM" "$SBX" # ---- 造假命令 ---- for cmd in systemctl iptables ip sysctl modprobe cloudflared apt-get apt \ service journalctl useradd groupadd chown chmod ln; do cat > "$SHIM/$cmd" <> $LOG # systemctl is-active 要回点像样的东西,不然脚本会走别的分支 case "\$1" in is-active) echo "active"; exit 0 ;; is-enabled) echo "enabled"; exit 0 ;; show) echo ""; exit 0 ;; esac exit 0 EOF chmod +x "$SHIM/$cmd" done : > "$LOG" echo "════════ 1. 记录运行前的真实系统状态(作为基线)════════" BASE_UNITS=$(ls /etc/systemd/system/ 2>/dev/null | md5sum | awk '{print $1}') BASE_CFG=$(md5sum /root/.cloudflared/config.yml 2>/dev/null | awk '{print $1}') BASE_RELAY=$(md5sum /root/lanremote-relay/relay.py 2>/dev/null | awk '{print $1}') BASE_IPT=$(iptables -t mangle -S 2>/dev/null | md5sum | awk '{print $1}') BASE_ENABLED=$(systemctl list-unit-files 2>/dev/null | grep -c lanremote || echo 0) echo " /etc/systemd/system 内容摘要: $BASE_UNITS" echo " /root/.cloudflared/config.yml: ${BASE_CFG:-(不存在)}" echo " /root/lanremote-relay/relay.py: ${BASE_RELAY:-(不存在)}" echo " iptables mangle 规则: $BASE_IPT" echo " lanremote 相关 unit 数: $BASE_ENABLED" echo echo "════════ 2. 用垫片 PATH 跑 deploy.sh --prefix $SBX ════════" if [ ! -f "$SCRIPT" ]; then echo " ! 找不到 $SCRIPT" echo " 试着找一下附近有没有 deploy.sh:" find /root /tmp -maxdepth 4 -name 'deploy.sh' 2>/dev/null | head -5 exit 1 fi echo " 脚本: $SCRIPT" # 只跑安装部分,跳过隧道(隧道要联网、要 token) PATH="$SHIM:$PATH" timeout 300 bash "$SCRIPT" \ --prefix "$SBX" --skip-tunnel 2>&1 | tail -40 | sed 's/^/ /' RC=${PIPESTATUS[0]} echo " 退出码: $RC" echo echo "════════ 3. 被调用的危险命令(关键证据)════════" if [ -s "$LOG" ]; then sort "$LOG" | uniq -c | sort -rn | sed 's/^/ /' else echo " (没有任何危险命令被调用 —— 沙箱很干净)" fi echo echo "════════ 4. 逐条判定 ════════" # a) systemctl 有没有操作真实服务(--prefix 模式下不该有) BAD_SYSCTL=$(grep -E '^systemctl (enable|start|restart|stop|disable|daemon-reload)' "$LOG" 2>/dev/null || true) if [ -n "$BAD_SYSCTL" ]; then echo " 🔴 沙箱模式下仍然调用了会改真实系统的 systemctl:" echo "$BAD_SYSCTL" | sed 's/^/ /' else echo " ✅ 没有调用会改真实系统的 systemctl" fi # b) 网络/内核改动 BAD_NET=$(grep -E '^(iptables|ip link|sysctl|modprobe)' "$LOG" 2>/dev/null || true) if [ -n "$BAD_NET" ]; then echo " 🟡 沙箱模式下调用了网络/内核命令:" echo "$BAD_NET" | sed 's/^/ /' else echo " ✅ 没有调用 iptables / ip link / sysctl / modprobe" fi # c) 文件有没有写到沙箱外 echo echo " ── 沙箱目录里生成了什么 ──" find "$SBX" -type f 2>/dev/null | head -20 | sed 's/^/ /' echo " 共 $(find "$SBX" -type f 2>/dev/null | wc -l) 个文件" echo echo " ── 真实系统有没有被改(对比基线)──" NOW_UNITS=$(ls /etc/systemd/system/ 2>/dev/null | md5sum | awk '{print $1}') NOW_CFG=$(md5sum /root/.cloudflared/config.yml 2>/dev/null | awk '{print $1}') NOW_RELAY=$(md5sum /root/lanremote-relay/relay.py 2>/dev/null | awk '{print $1}') NOW_IPT=$(iptables -t mangle -S 2>/dev/null | md5sum | awk '{print $1}') NOW_ENABLED=$(systemctl list-unit-files 2>/dev/null | grep -c lanremote || echo 0) [ "$BASE_UNITS" = "$NOW_UNITS" ] && echo " ✅ /etc/systemd/system 没变" || echo " 🔴 /etc/systemd/system **变了**" [ "$BASE_CFG" = "$NOW_CFG" ] && echo " ✅ cloudflared config 没变" || echo " 🔴 cloudflared config **变了**" [ "$BASE_RELAY" = "$NOW_RELAY" ] && echo " ✅ 现有 relay.py 没变" || echo " 🔴 现有 relay.py **变了**" [ "$BASE_IPT" = "$NOW_IPT" ] && echo " ✅ iptables 没变" || echo " 🔴 iptables **变了**" [ "$BASE_ENABLED" = "$NOW_ENABLED" ] && echo " ✅ unit 启用状态没变 ($NOW_ENABLED)" || echo " 🔴 unit 启用状态变了:$BASE_ENABLED -> $NOW_ENABLED" echo echo "════════ 5. 再跑一遍,验证幂等性 ════════" : > "$LOG" PATH="$SHIM:$PATH" timeout 300 bash "$SCRIPT" \ --prefix "$SBX" --skip-tunnel > /tmp/sbx_run2.log 2>&1 echo " 第二次退出码: $?" echo " 第二次有没有非 0 退出/报错行:" grep -ciE 'error|错误|失败|✗' /tmp/sbx_run2.log | sed 's/^/ 匹配行数: /' tail -6 /tmp/sbx_run2.log | sed 's/^/ /' echo echo " 沙箱最终文件数: $(find "$SBX" -type f 2>/dev/null | wc -l)"