团队小伙伴在应急的时候发现了一个样本,然后丢给了我,网上一查发现360的博客已经分析的很详细了,并且调试符号都在,索性对着跑一边试试,于是就有了这篇文章。
strings
拿到样本之后首先strings跑一遍,发现存在以下文件名,因此需要对以下文件重点关注:
MD5
和网络上的木马不一样,微步在线分析的马md5值为c8ba8bcfd8f068a19b89f112e80a9e56
,但是本地计算文件的md5值为a011ae821ae822bade7ef4f396dcc20c
,本次捕获到的样本文件中,ss、getty和.sshd的文件hash相同,估计是盖茨木马的变种吧。
ghidra反编译
直接丢ghidra中反编译,发现调试符号都在,感谢编译人员,好人一生平安。。。
Ower6msf函数
跟进去,发现是解密函数。
写一下这个函数的大致执流程:在上图25行的位置QQifu6函数执行得到的内容为/usr/bin/.sshd:30000:1223123:772124:773152:4f58574098255d
然后之后的过程均为将该字符串通过:
分割后分别对以下变量赋值的过程:
-
g_strMonitorFile
=/usr/bin/.sshd
-
g_uhiddenPt
=30000 -
g_iFileSize
=1223123
-
g_iHardStart
=772124
-
g_iSoftStart
=773152
-
g_strDoFun
=4f58574098255d
反调试的部分:
通过GetParentPath
函数得到父进程的文件名和路径,然后对gdb字符串进行比对,如果cunzgdb字符串则直接退出。
获取文件名称
-
g_strSN
的结果由HGrd9()
函数得到,为DbSecuritySpt
-
g_strBDSN
的结果由Mndyuf()
函数得到,为selinux
-
g_strBDG
的结果由BGtd98()
函数获得,为getty
-
g_strML
的结果由Osdku6()
函数获得,为/tmp/moni.lod
-
g_strGL
的结果由wer54()
函数获得,为/tmp/gates.lod
checkGatesType函数
-
得到本文件字符串和
g_strMonitorFile
进行对比,如果两者相同,则g_iGatesType
赋值为0 -
如果上面比较不为零,则比较
/usr/bin/bsd-port/getty
和本文件路径文件名,如果两者相同,则g_iGatesType
赋值为2 -
如果上面比较不相同,则比较文件名与
["/bin/netstat"、"/bin/lsof"、"/bin/ps"、"/bin/ss"、"/usr/bin/netstat"、"/usr/bin/lsof"、"/usr/bin/ps"、"/usr/bin/ss"、"/usr/sbin/netstat"、"/usr/sbin/lsof"、"/usr/sbin/ps"、"/usr/sbin/ss"]
列表中所有文件名进行比较,如果存在则g_iGatesType
设置为3,如果不存在g_iGatesType
设置为1。
即
当前运行程序所在路径 |
g_iGatesType |
|
0 |
其他 |
1 |
|
2 |
上方第三点中文件名列表中任意一项 |
3 |
Ikdfu94函数
解密函数,对加密字符串进行解密,解析出字符串115.231.218.64:8226:1:1:ssh4ckss:1
对方ip115.231.218.64:8226
-
g_strConnTgts
=115.231.218.64
-
g_iGatsPort
=8226
-
g_iGatsIsFax
=1
-
g_iIsService
=1
-
g_strForceNote
=ssh4ckss
-
g_iDoBackdoor
=1
同理解析字符串erwu.googtg.com:1103:1:1:ȥ272363303305:1
对方域名erwu.googtg.com
IsUpdateTemporary函数
判断函数名是否为update_temporary,如果是则进入Doupdate函数。
MainBeikong
函数执行流程:
-
kill
/tmp/moni.lod
-
kill
/tmp/bill.lock
-
删除
tmp/bill.lock
-
在SetAutoStart函数中设置启动项
/etc/init.d/DbSecuritySpt
,然后在/etc/rc1.d
~/etc/rc5.d
下设置软链接。 -
结束/usr/bin/bsd-port/下getty.lock和udevd.lock对应的进程,
-
删除udevd.lock
-
复制自身到/usr/bin/bsd-port/getty并启动
-
/usr/bin/bsd-port/getty并启动。
-
复制当前文件到/usr/bin/.sshd(对应MainMonitor)并启动。
-
运行MainProcess
MainBackdoor函数
进入daemon,设置pid文件,
-
以 selinux为服务名创建启动项。
-
移动系统程序ps、ss、netstat、lsof到/usr/bin/dpkgd/目录
-
复制自身到/bin、/usr/bin、/usr/sbin下替换ps、ss、netstat、lsof
-
执行MainProcess。
MainSystool函数
-
获取当前文件路径
-
获取/usr/bin/dpkgd/中的ps、ss、netstat、lsof
-
执行相关命令并对和程序有关的内容过滤掉
MainMonitor
函数执行流程:
-
进入daemon
-
创建
/tmp/moni.lod
-
写入
/tmp/notify.file
-
创建线程
CThreadMonGates
-
判断
/tmp/gates.lod
是否存在,若不存在则在/tmp/notify.file复制 -
sleep3600秒
参考:https://blogs.360.net/post/某僵尸网络被控端恶意样本分析.html
原文始发于微信公众号(Wings安全团队):BillGates木马分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论