登录脚本注入是什么
Linux 的 shell 在启动时会按固定顺序读取一批配置文件,用来设置环境变量、别名与提示符。攻击者把一条下载执行或反弹命令塞进这些文件,就得到一种「无需任何服务守卫」的持久化:只要有人用该账号登录,命令就会被执行。它的隐蔽性在于文件本身是系统自带且内容冗长,随手一看很难发现多出来的一行。排查用户会话安全时,这一站不能跳过。
基本信息
| 系统级登录文件 | /etc/profile 与 /etc/profile.d/*.sh,登录 shell 依次读取 |
|---|---|
| 系统级交互文件 | Debian 系 /etc/bash.bashrc,RHEL 系 /etc/bashrc |
| 用户级登录文件 | ~/.bash_profile、~/.bash_login、~/.profile,取第一个存在者 |
| 用户级交互文件 | ~/.bashrc,非登录的交互式 shell 读取它 |
| 其他 shell | zsh 用户看 ~/.zshrc、~/.zprofile;csh 用户看 ~/.cshrc |
| 常被忽略的位置 | sshd 在登录时会执行 ~/.ssh/rc(PermitUserRC 默认为 yes) |
典型使用场景
- 确认木马是否通过登录脚本实现「每次登录回连」,这类后门不会出现在进程常驻列表里
- 排查某账号一登录就出现异常网络连接、异常环境变量的情况
- 清理后做复查,确认新开会话不再触发可疑动作
- 做主机基线时留存这些文件的哈希,便于日后发现被改动
- 与前几个排查点联用,构成完整的持久化清理清单
扫描登录脚本注入
扫描登录脚本注入
grep -rEn 'curl|wget|base64|/dev/tcp|nc -e|python -c|bash -i' \
/etc/profile /etc/profile.d/ /etc/bash.bashrc /etc/bashrc /root/.bashrc /root/.profile 2>/dev/null | head -n 40
ls -lt --time-style=full-iso /etc/profile.d/ | head -n 20 # 看最近被改动或新增的脚本
for h in /root /home/*; do for f in .bashrc .bash_profile .profile .zshrc; do
[ -f "$h/$f" ] && { echo "== $h/$f"; tail -n 20 "$h/$f"; }; done; done # 直接看文件尾部
grep -RnE 'PROMPT_COMMAND|trap .*DEBUG|alias ' /etc/bash.bashrc /root/.bashrc 2>/dev/null | head -n 20文件与加载时机
| 文件 | 加载时机 | 排查要点 |
|---|---|---|
| /etc/profile | 登录 shell 启动时 | 系统级,改动会影响所有用户,重点看文件尾部追加内容 |
| /etc/profile.d/*.sh | 被 /etc/profile 循环加载 | 目录化最容易被忽略,注意随机命名的 .sh 文件 |
| ~/.bashrc | 每次交互式 shell 启动 | 最常被注入的位置,含别名与环境变量改写 |
| ~/.bash_profile 与同类 | 登录 shell 启动时 | 常被追加 source 一行,指向 payload 脚本 |
| ~/.ssh/rc | sshd 建立会话后执行 | 不需要 shell 配置被改也能触发,排查时容易漏 |
| /etc/environment | PAM 设置环境变量 | 只做变量赋值不执行脚本,但可通过 BASH_ENV 间接影响 |
改这些文件影响所有新会话,属于高危操作:改前把原文件复制到证据目录并记录 sha256,改后用新终端登录一次确认环境变量、提示符与业务脚本都正常,避免把自己锁在门外或让自动化任务失败。
只 grep 关键词会漏掉混淆写法:把命令拆成变量拼接、写成 base64 解码、或挂在 PROMPT_COMMAND 与 trap DEBUG 上,都不会出现 curl 字样。做法是先与基线副本做 diff,再人工通读可疑文件的尾部若干行。
留证与清理
留证与清理
sudo tar -zcPpf /evidence/profile_$(date +%F).tgz /etc/profile /etc/profile.d /etc/bash.bashrc /root/.bashrc 2>/dev/null
sudo sha256sum /etc/profile /etc/profile.d/*.sh 2>/dev/null | tee /evidence/profile_hash.txt
sudo cp -a /etc/profile /evidence/profile.bak # 单文件备份,便于回滚
sudo sed -i '/可疑片段/d' /etc/profile # 按行删除,删前确认行号
sudo grep -Rn '可疑片段' /etc/profile /etc/profile.d/ # 删除后复查别忘了非 bash 场景:把命令写进用户的 crontab、systemd 用户单元或 ~/.ssh/rc 都能获得类似效果,清理登录脚本只是持久化清单中的一项。
检测思路对照
| 手段 | 能发现什么 | 局限 |
|---|---|---|
| 关键词 grep | 明显的下载执行、编码命令、反弹写法 | 变量拼接与编码混淆抓不到 |
| 与基线副本 diff | 任何新增或改写的行,最可靠 | 前提是事先留存过基线哈希 |
| 通读文件尾部 | 追加型注入与 PROMPT_COMMAND 改写 | 依赖人工,文件多时耗时 |
| 看 mtime 排序 | 最近被改动或新增的配置文件 | 正常运维操作同样会改动时间 |
| 审查登录后行为 | 会话建立瞬间产生的异常进程与外联 | 需要在受控环境复现,生产机上谨慎操作 |
基线是这类排查的前提:日常把 /etc/profile、/etc/profile.d/*.sh、各账号 rc 文件的 sha256 与内容副本留档,出事时一个 diff 就能定位到具体行,比手工通读快得多。