龙空技术网

卷土重来的DDoS狂魔:Fodcha僵尸网络再次露出獠牙

码农世界 273

前言:

现在兄弟们对“btea算法”大约比较看重,大家都想要了解一些“btea算法”的相关文章。那么小编也在网络上网罗了一些有关“btea算法””的相关内容,希望兄弟们能喜欢,你们快快来学习一下吧!

背景

2022年4月13日,360Netlab首次向社区披露了Fodcha僵尸网络,在我们的文章发表之后,Fodcha遭受到相关部门的打击,其作者迅速做出回应,在样本中留下Netlab pls leave me alone I surrender字样向我们投降。本以为Fodcha会就此淡出江湖,没想到这次投降只是一个不讲武德的假动作,Fodcha的作者在诈降之后并没有停下更新的脚步,很快就推出了新版本。

在新版本中,Fodcha的作者重新设计了通信协议,并开始使用xxtea和chacha20算法对敏感资源和网络通信进行加密,以躲避文件&流量层面的检测;同时引入了OpenNIC 域名做为主选C2,ICANN 域名做为后备C2的双C2方案。这种冗余机制,既能防止C2被接管,又有良好的健壮性,能够维持其主控网络的稳定。

依托于背后团队强大的N-day漏洞整合能力,卷土重来的Focha与之前对比可谓有过之而无不及。在我们的数据视野中,从规模来看,Fodcha再次发展成日活Bot节点数超过60K,C2域名绑定40+IP,可以轻松打出超过1Tbps流量的大规模僵尸网络;就活跃程度而言,Fodcha日均攻击目标100+,累计攻击目标2万多,在10月11日到达了攻击的巅峰,单日“丧心病狂”的攻击了1396个目标

在极短的时间内重回巅峰,Fodcha的作者似乎忘了闷声发大财的道理,竟然又开始主动"招惹”我们,在某次扫描的脚本中使用N3t1@bG@Y字样的leetspeak,翻译过来就是"NETLABGAY",这么明目张胆的黑Netlab,让我们觉得它多多少少有些“皮痒”了。

鉴于Fodcha的规模&活跃程度带来的巨大危险性,以及非常嚣张的挑衅,我们决定撰写本文向社区分享我们的发现,一起打击Fodcha的嚣张气焰,共同维护网络安全。

时间线

依托于360Netlab强大的BotMon和DDoSMon系统,我们对Fodcha的样本演变和DDoS攻击指令一直保持着良好跟踪,下面是我们看到的样本演变以及一些重要的DDoS攻击事件。(注:Fodcha样本本身没有特定的标志表明其版本,这是我们内部为了跟踪方便而定的版本号)

2022年1月12日,首次捕获到Fodcha僵尸网络样本。2022年4月13日,首次向外披露Fodcha僵尸网络,包含版本V1,V2。2022年4月19日,捕获版本V2.x,使用OpenNIC's TLDs风格的C2(全文简称OpenNIC C2)。2022年4月24日,捕获版本V3,使用xxtea算法加密配置信息,新增ICANN's TLDs风格的C2(全文简称ICANN C2),和OpenNIC C2构成冗余机制;新增反沙箱&反调试机制。2022年6月5日,捕获版本V4,使用结构化的配置信息,去除反沙箱&反调试机制。2022年6月7&8日,监控到Fodcha对某国的某地的健康码机构进行了DDoS攻击。2022年7月7日,捕获版本V4.x,额外新增一组ICANN C2。2022年9月X日,在协助某国的某执法机构固定某公司语音业务被DDoS攻击的证据链过程中,发现攻击背后有Fodcha的影子。2022年9月21日,某知名云服务商就一起流量超过1Tbps的攻击事件向我们咨询,经过数据的交叉比对,确定攻击方为Fodcha。规模推测

国外合作伙伴的数据表明Fodcha 4月份时全球日活Bot的数量为6W(参考我们另一篇文章),关于Fodcha僵尸网络的目前规模,我们没有确切的数字,但通过对比Fodcha 4月和10月在C2 IP数量上的差异,我们从技术上出发,有个未经验证的猜测:目前Fodcha的日活Bot数量超过6W。

推测过程如下:

僵尸网络的规模与C2 IP的数量存在一个正向关系,最朴素的观点是:“僵尸网络规模越大,所需要的C2基础设施也越多”。在4月份,Fodcha被处置之前,其作者为维持6W的规模,投入了10个C2 IP;随后Fodcha开始了自己的复活之旅,我们观察到一个现象,随着Fodcha的复苏,其C2域名对应的IP在持续增加。时至今日,Fodcha的作者投入了多少C2 IP呢?使用dig命令查询最新的C2域名yellowchinks.dyn的绑定IP,可以看到数量是44。

可以说我们见证了Fodcha的C2 IP一步步从几个增长到今天的40+,可能的解释是作者人傻钱多无脑上资源,但结合其迅猛的传播以及历史上曾看到的万级规模,他们增加C2 IP更可能的原因是因为其僵尸网络规模太大,需要投入更多的IP资源,以使Bot与C2之间在数量上有一个合理比例,达到负载均衡。

综上,我们从C2 IP数量上大幅度的增长,推测目前Fodcha的规模大于4月份,日活Bot数量超过6W。当然再合理的推测也还是假设,欢迎有视野的社区伙伴不吝指正

DDoS统计

回到C2 IP 44这个数字本身,纵然我们和僵尸网络battle多年见多识广,但这个数字依然让我们感到惊讶。世上没有无缘故的爱,光是这些IP资源,就得花费不少的,Fodcha的作者为什么愿意花这个钱呢?答案是DDoS攻击让他赚到了钱。我们节选了2022年6月29至今的数据,其攻击趋势和目标区域分布如下:

可以看出:

无愧于DDoS狂魔的称号,攻击几乎没有停歇,几乎打遍全球,日均攻击事件1K+。中美两国颜色较深,说明两国累计被攻击目标及次数较多,综合考虑到两国在互联网上业务的比重原本就比较大,这里的“看起来多”是一种正常状况。

攻击指令在7天内的时间分布如下所示,可以看出Fodcha发起的DDoS攻击遍及7 * 24小时,没有明显的时区性,我们倾向Fodcha是一个商业驱动的僵尸网络。

样本分析

我们将捕获的样本分成了4个大版本,其中在上一篇blog中已经分析过V1V2,此处就不再赘述了,本文选取最新的V4系列样本为主要分析对象,它们的基本信息如下所示:

MD5: ea7945724837f019507fd613ba3e1da9ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), strippedLIB: uclibcPACKER: Noneversion: V4MD5: 899047ddf6f62f07150837aef0c1ebfbELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, strippedLib: uclibcPacker: NoneVersion: V4.X

Fodcha的Bot在被侵入设备运行时,首先会从运行参数网络的连通性是否设置“LD_PRELOAD”环境变量自身是否被调试等方面进行检查,如果不满足要求就直接退出,这些检查可以看成是一种对通过模拟器&沙箱提取IOC的简单对抗。

当满足要求运行要求时,则首先解密出配置信息,在Console上输出snow slide,然后就是一些常见的主机行为,如单一实例,进程名伪装,操控watchdog,清空特定端口进程,上报特定进程信息等,我们认为这些主机侧的功能没有太多亮点,因此不再展开分析,下文将着重从解密配置信息,网络通信,DDoS攻击等方面对Fodcha进行剖析。

解密配置信息(Config)

Fodcha在V2.X,V3使用并列的Config组织方式,而在V4,V4.X中则使用结构化的Config组织方式,下图非常清楚的显示了它们的区别。

虽然Config的组织方法不一样,但它们的加密方法是一样的,通过下面代码片段引用的常量可知,它们使用的是xxtea算法,密钥为PJbiNbbeasddDfsc

经过逆向,我们编写了以下IDAPYTHON脚本来解密配置信息。

# md5: ea7945724837f019507fd613ba3e1da9# requirement: pip install xxtea-py# test: ida7.6_python3import ida_bytesimport xxteaBufBase=0x1F2B0ConfBase=0x0001F1A0key=b"PJbiNbbeasddDfsc"for i in range(17):    offset=ida_bytes.get_word(i*16+ConfBase+2)    leng=ida_bytes.get_word(i*16+ConfBase+4)-offset    buf=ida_bytes.get_bytes(BufBase+offset,leng)    print("index:%d, %s" %(i,xxtea.decrypt(buf,key)))

解密后的Config信息如下表所示,可以看到index 11还保留着“投降”的彩蛋,另外值得一提的是index 12,它是reporter服务器地址,Fodcha会将一些特定进程的信息上报给它。

INDEX

VALUE

0

snow slide

1

/proc/

2

/stat

3

/proc/self/exe

4

/cmdline

5

/maps

6

/exe

7

/lib

8

/usr/lib

9

.ri

10

GET /geoip/?res=10&r HTTP/1.1\r\nHost: 1.1.1.1\r\nConnection: Close\r\n\r\n

11

Netlab pls leave me alone I surrender

12

kvsolutions.ru

13

api.opennicproject.org

14

watchdog

15

/dev/

16

TSource Engine Query

网络通信

Fodcha的网络通信在代码层面有一个非常固定的特点:一个永真的While循环,通过switch-case进行各个阶段的处理,因此Fodcha各个版本的网络协议处理函数在IDA中产生的CFG图高度相似,这个特点可以帮助我们对样本进行辨别,对功能快速定位。

总的来说,Fodcha的网络通信要经过以下4个步骤:

解密C2DNS查询建立通信执行指令0x1: 解密C2

Fodcha的不同版本支持的C2种类是不一样的,V2.X只有1组OpenNIC C2;V3&V4拥有1组OpenNIC C2,1组ICANN C2;而V4.X则是最多的,1组OpenNIC C2,2组ICANN C2,下面的图非常清楚的显示了它们的区别。

虽然C2种类&数量不一样,但是它们的处理逻辑如下图所示,几乎是一样的,首先通过C2_GET函数获得一个C2域名,然后通过DNS_QUERY函数获得C2对应的IP,其中C2_GET的第一个参数为C2密文数据,第2个参数为长度,而DNS_QUERY的第2个参数则暗示了C2的类型。

通过C2_GET可以获得一个有效的C2域名,它内部的实现可以分成2步:

首先得解密C2密文数据。然后将它们构造成一个合法的域名。解密C2密文数据

C2的密文数据使用了配置信息一样的加密方式,即xxtea,密钥也是PJbiNbbeasddDfsc,通过下面简单的IDAPYTHON脚本,即可解密出OpenNic C2数据。

#md5: 899047DDF6F62F07150837AEF0C1EBFBimport xxteaimport ida_bytesimport hexdumpkey=b"PJbiNbbeasddDfsc"buf=ida_bytes.get_bytes(0x0001CA6C,1568)  # Ciphertext of OpenNic C2plaintext=xxtea.decrypt(buf,key)print(plaintext)

解密后的C2数据如下图所示,可以看出C2数据由2部分组成,前面的是domain names,后面是TLDs,它们通过红框中的“/”符号分隔。

构造域名

Fodcha有一个特定的域名构造方法,等效的Python实现如下所示:

# md5: 899047ddf6f62f07150837aef0c1ebfb# requirement: pip install xxtea-py# test: ida7.6_python3import xxteaimport ida_bytesdef getcnt(length):    cnt=1    while True:        cnt +=1        calc=2                for i in range(1,cnt):            calc+=2+12*i%cnt                            if calc +cnt==length-1:            return cnt                        key=b"PJbiNbbeasddDfsc"buf=ida_bytes.get_bytes(0x0001CA6C,1568)  # Ciphertext of OpenNic C2plaintext=xxtea.decrypt(buf,key)domains,tlds=plaintext.split(b'/')domainList=domains.split(b',')tldList=tlds.split(b',')cnt=getcnt(len(domainList))print("------------There're %d C2------------" %cnt)coff=2for i in range(0,cnt):    if i ==0:        c2Prefix=domainList[i+coff]    else:        coff+=12*i %cnt+2        c2Prefix=domainList[i+coff]    c2Tld=tldList[(cnt-i-1)*3]    print(c2Prefix + b'.' + c2Tld)

将上文得到的C2数据做为输入,最终构造出以下14个OpenNIC C2。

techsupporthelpars.ossyellowchinks.geekyellowchinks.dynwearelegal.geekfunnyyellowpeople.librechinksdogeaters.dynblackpeeps.dynpepperfan.geekchinkchink.librepeepeepoo.librerespectkkk.geekbladderfull.indytsengtsing.libreobamalover.pirate

对ICANN域名体系熟悉的读者,或许会在第一眼就认为我们的解密是错误的,因为ICANN的域名体系并不支持这些TLDs,它们肯定“无法解析”,事实上它们正是OpenNIC体系下的域名,OpenNIC是独立于ICANN的另一套域名体系,它支持下图所示的TLDs,OpenNIC的域名无法通过常见的DNS(如8.8.8.8,101.198.198.198)解析,必须使用指定的NameServer,更多的细节就不再展开,感兴趣的读者自行到其官方网站了解。

用同样的方法,我们可以得到以下4个ICANN C2。

cookiemonsterboob[.]comforwardchinks[.]comdoodleching[.]commilfsfors3x[.]com
0X2: DNS查询

当成功获得C2域名后,Bot通过函数DNS_QUERY进行域名解析,它的第2个参数是一个FLAG,暗示了OpenNIC/ICANN C2的不同处理过程,相应的代码片段如下所示:

可以看出对于OpenNIC C2的解析有2个选择:

选择1:通过API接口向api.opennicproject.org请求,动态的获取nameserver选择2:使用下图所示的硬编码nameserver

而对于ICANN C2则只有一个选择,即使用下图中的硬编码nameserver。

以实际解析 C2“techsupporthelpars.oss”为例,它的解析过程在网络流量中的体现如下所示:

为什么使用OpenNIC / ICANN 双C2?

Fodcha作者构建了一套OpenNIC / ICANN 双C2的冗余结构,他为什么要这么做呢?

从C2基础设施的角度出发,Fodcha被曝光后,其C2被一些服务商加入到了监控列表,进行拦截。例如Quad9DNS(9.9.9.9)就曾发过一个关于Fodcha域名流量spike的Twitter

在Fodcha被打击之后,其作者在重新选择C2基础设施时,看中了OpenNIC宣传的"DNS Neutrality"特性,通过绕开ICANN的域名体系,从根本上消除C2被监管&接管的可能性,因此Fodcha在V2.X引入OpenNic C2,并将其做为主C2。

与此同时,OpenNIC C2可能存在一些问题,比如OpenNIC的NameServer在某些地区可能无法访问,或者域名解析上存在效率或稳定性的问题。出于健壮性的考虑,Fodcha作者在V3之 后重新加入ICANN C2作为后备C2,与主C2构成冗余结构。

0x3: 建立通信

Fodcha Bot通过又下代码片段和C2建立连接,一共有个22个端口。

当成功和C2建立连接后,Bot与C2必须经过3个阶段的交互,才能真正建立通信。

阶段1:Bot向C2请求chacha20加密算法的的key&nonce。阶段2:Bot与C2使用阶段1的key&nonce进行身份确认。阶段3:Bot将加密后的上线&分组信息发往C2。

为了辅助分析,我们在受限的环境内运行了Bot样本,并使用fsdsaD做为分组字串,产生了下图所示的网络流量,下文将详细介绍此流量是如何生成的。

阶段1:Bot ---> C2 ,格式为head(7 bytes) + body( random 20-40 bytes)

Bot主动向C2发送netstage=6的初始化消息,这个消息的格式为head+body,各字段含义如下所示:

head

head的长度为7 bytes,格式如下所示:

06     		---->netstage,1byte,06 means initf0 70       ---->tcpip checksum, 2byte, 00 16		---->length of body, 2 bytes
checksum

head中的checksum使用的是tcp/ip的checksum,它计算对象为整个payload,checksum所在偏移的原始值为"\x00\x00",checksum的python实现如下所示:

def checksum(data):    s = 0    n = len(data) % 2    for i in range(0, len(data)-n, 2):        s+= ord(data[i]) + (ord(data[i+1]) << 8)    if n:        s+= ord(data[-1])    while (s >> 16):        s = (s & 0xFFFF) + (s >> 16)        s = ~s & 0xffff    return sbuf="\x06\x00\x00\x00\x00\x00\x16\x36\x93\x93\xb7\x27\x5c\x9a\x2a\x16\x09\xd8\x13\x32\x01\xd2\x69\x1d\x25\xf3\x42\x00\x32"print(hex(checksum(buf)))#hex(checksum(buf))#0x70f0
body

body为随机生成的内容,无意义。

00000000  36 93 93 b7 27 5c 9a 2a 16 09 d8 13 32 01 d2 6900000010  1d 25 f3 42 00 32
阶段1:C2--->Bot,共2轮

当C2收到Bot的netstage=6的消息后,就会向BOT发送2轮的数据。

第一轮,36 bytes , 原信息被xxtea加密,解密后作为chacha20的key,长度为32bytesimport hexdump import xxtea key=b"PJbiNbbeasddDfsc" keyBuf=bytes.fromhex("806d8806cd5460d8996339fbf7bac34ba1e20f792872ba0e05d096ad92a5535e60e55b8d") chaKey=xxtea.decrypt(keyBuf,key) hexdump.hexdump(chaKey) #chaKey 00000000: E6 7B 1A E3 A4 4B 13 7F 14 15 5E 99 31 F2 5E 3A 00000010: D7 7B AB 0A 4D 5F 00 EF 0C 01 9F 86 94 A4 9D 4B第二轮,16 bytes,原信息被xxtea加密,解密后作为chacha20的nonce,长度12bytesimport hexdump import xxtea key=b"PJbiNbbeasddDfsc" nonBuf=bytes.fromhex("22c803bb310c5b2512e76a472418f9ee") chaNonce=xxtea.decrypt(nonBuf,key) hexdump.hexdump(chaNonce) #chaNonce 00000000: 98 79 59 57 A8 BA 7E 13 59 9F 59 6F阶段2:Bot--->C2,chacha20加密

Bot收到chacha20的key和nonce后,就向C2发送netstage=4的消息,此次消息使用chacha20加密,key&nonce由上一阶段获得,加密的轮数为1。

我们可以使用下面的python代码可以解密上面的流量,

from Crypto.Cipher import ChaCha20cha=ChaCha20.new(key=chaKey,nonce=chaNonce)cha.seek(64)tmp=bytes.fromhex('dc23c56943431018b61262481ce5a219da9480930f08714e017edc56bf903d32ac5daeb8314f1bf7e6')rnd3=cha.decrypt(tmp)

解密后的流量如下所示,它的格式依然是前文所述的head(7 bytes)+body,其中head的netstage字段的值为04,代表身份认证。

阶段2:C2--->Bot,chacha20加密

C2在收到Bot的身份认证消息后,也向Bot的数据发送netstage=4的消息,同样使用chacha20加密,且key,nonce,轮数和Bot使用的是一样的。

使用和Bot相同的代码解密流量,可以看出它的格式也是head+body,netstage的值也为04。

在Bot和C2互发netstage=4的消息之后,代表阶段1的chacha20 key&nonce被双方认可,彼此的身份认证完成,Bot进入下一阶段准备上线。

阶段3:Bot--->C2,共2轮,chacha加密

Bot向C2发送netstage=5的消息,表示准备上线,接着再自己的分组信息上报给C2,这2轮消息也使用chacha20加密。

第一轮第二轮

上述2轮的数据解密后如下所示,可以看出分组的内容正是预设的"fsdsaD",这代表我们的分析是正确的,至此Bot成功上线,开始等待执行C2下发的指令。

0x4:执行指令

Bot成功上线后,支持的netstage编号,如下所图所示,其中最重要的就是netstage=1代表DDoS任务,Fodcha复用了大量Mirai的攻击代码,一共支持17种攻击方法。

以下图的DDos_Task流量(netstage=01)为例:

攻击指令依然采用chacha20加密,解密后的指令如下所示,相信熟悉Mirai的读者看到此处肯定会心一笑。

00000000: 00 00 00 3C 07 01 xx 14  93 01 20 02 00 00 02 0100000010: BB 01 00 02 00 01

上述攻击指令的格式和解析方式如下表所示:

OFFSET

LEN (BYTES)

VALUE

MEANING

0x00

4

00 00 00 3c

Duration

0x04

1

07

Attack Vector,07

0x05

1

1

Attack Target Cnt

0x06

4

xx 14 93 01

Attack Target,xx.20.147.1

0x0a

1

20

Netmask

0x0b

1

02

Option Cnt

0x0c

5

00 00 02 01 bb

OptionId 0,len 2, value 0x01bb ---> (port 443)

0x11

5

01 00 02 00 01

OptionId 1, len 2, value 0x0001---> (payload len 1 byte)

当Bot接收到上述指令,就会使用payload为1字节的tcp报文对目标xx.20.147.1:443进行DDoS攻击,这和实际抓包的流量是能对应上的。

花絮0x01: 种族歧视

从某些OpenNIC C2的构词上来说,Fodcha的作者似乎对黄种人,黑人有比较大的敌意。

yellowchinks.geekwearelegal.geekfunnyyellowpeople.librechinksdogeaters.dynblackpeeps.dynbladderfull.indywehateyellow
0x02: 攻击即勒索

Fodcha曾在其下发的UDP攻击指令中,附带以下字串:

send 10 xmr to 49UnJhpvRRxDXJHYczoUEiK3EKCQZorZWaV6HD7axKGQd5xpUQeNp7Xg9RATFpL4u8dzPfAnuMYqs2Kch1soaf5B5mdfJ1b or we will shutdown your business

Bot打出的攻击流量如下所示,该钱包地址似乎是非法的,没能给我们更多的线索,但从这一行为出发,或许Fodcha背后的运营者正在尝试攻击即勒索这种商业模式。

联系我们

感兴趣的读者,可以在 twitter 或者通过邮件netlab[at]360.cn联系我们。

解决方案

基于Netlab多年研究工作孵化的360全系列DNS安全产品均已支持文中远控服务器的拦截和检测,同时内置多种算法可有效发现和拦截各种未知威胁,建议企业客户接入360 DNS安全SaaS平台或部署本地360DNS安全产品,及时防范此类新型威胁,避免企业资产失陷。联系人: wangkun-bd@360.cn

IoCC2

yellowchinks.geekyellowchinks.dynwearelegal.geektsengtsing.libretechsupporthelpars.ossrespectkkk.geekpepperfan.geekpeepeepoo.libreobamalover.piratemilfsfors3x[.]comfunnyyellowpeople.librefridgexperts[.]ccforwardchinks[.]comfolded[.]indoodleching[.]comcookiemonsterboob[.]comchinksdogeaters.dynchinkchink.librebladderfull.indyblackpeeps.dyn91.206.93.24391.149.232.12991.149.232.12891.149.222.13391.149.222.13267.207.84.8254.37.243.7351.89.239.12251.89.238.19951.89.176.22851.89.171.3351.161.98.21446.17.47.21246.17.41.7945.88.221.14345.61.139.11645.41.240.14545.147.200.16845.140.169.12245.135.135.333.70.127.2413.65.206.2293.122.255.2253.121.234.2373.0.58.14323.183.83.171207.154.206.0207.154.199.110195.211.96.142195.133.53.157195.133.53.148194.87.197.3194.53.108.94194.53.108.159194.195.117.167194.156.224.102194.147.87.242194.147.86.22193.233.253.93193.233.253.220193.203.12.157193.203.12.156193.203.12.155193.203.12.154193.203.12.151193.203.12.123193.124.24.42192.46.225.170185.45.192.96185.45.192.227185.45.192.212185.45.192.124185.45.192.103185.198.57.95185.198.57.105185.183.98.205185.183.96.7185.143.221.129185.143.220.75185.141.27.238185.141.27.234185.117.75.45185.117.75.34185.117.75.119185.117.73.52185.117.73.147185.117.73.115185.117.73.10918.185.188.3218.136.209.2178.62.204.81176.97.210.176172.105.59.204172.105.55.131172.104.108.53170.187.187.99167.114.124.77165.227.19.36159.65.158.148159.223.39.133157.230.15.8215.204.18.23215.204.18.20315.204.128.25149.56.42.246139.99.166.217139.99.153.49139.99.142.215139.162.69.4138.68.10.149137.74.65.16413.229.98.186107.181.160.173107.181.160.172
Reporter
kvsolutions[.]ruicarlyfanss[.]com
Samples
ea7945724837f019507fd613ba3e1da9899047ddf6f62f07150837aef0c1ebfb0f781868d4b9203569357b2dbc46ef10

原文地址:

标签: #btea算法 #xxteapython #pythonxxtea