Dacls, the Dual platform RAT
<!--kg-card-begin: markdown--><h2 id="background">Background</h2>
<p>On October 25, 2019, a suspicious ELF file (80c0efb9e129f7f9b05a783df6959812) was flagged by our  new threat monitoring system. At first glance, it seems to be just another one of the regular botnets, but we soon realized this is something with potential link to the Lazarus Group.</p>
<p>At present, the industry has never disclosed the Lazarus Group's attack samples and cases against the Linux platform. And our analysis shows that this is a fully functional, covert and RAT program targeting both Windows and Linux platforms, and the samples share some key characters being used by Lazarus Group.</p>
<h3 id="thelinksbetweenlazarusgroupanddaclsrat">The links between Lazarus Group and Dacls RAT</h3>
<p>First, we searched VT for the hardcoded string <code>c_2910.cls</code> and <code>k_3872.cls</code> in the sample and found 5 more samples. We can confirm from their sample and C2 instruction codes that they are the same RAT family, and is suitable for Windows and Linux platforms, respectively.</p>
<p>One of the 5 samples <code>6de65fc57a4428ad7e262e980a7f6cc7</code> was pointed to as Lazarus Group by the user Raeezabdulla of the VirusTotal community, and cited a report &quot;CES Themed Targeting from Lazarus&quot;. This sample also has download address of <code>https://thevagabondsatchel.com/wp-content/uploads/2019/03/wm64.avi</code>. In October 2019, a sample named NukeSped was tagged by Twitter user @cyberwar_15 as Lazarus Group. And that sample file <code>b578ccf307d55d3267f98349e20ecff1</code> has the download url as <code>http://thevagabondsatchel.com/wp-content/uploads/2019/09/public.avi</code></p>
<p>A quick google returns many Lazarus Group analysis reports and some open source threat intelligence data, many pointing out that thevagabondsatchel.com was used by Lazarus Group to store samples.</p>
<p>Therefore, we speculate that the attacker behind Dacls RAT is Lazarus Group.<br>
<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>
<p>Currently this sample is shown on VirusTotal with 26 pretty generic malware tag from by 26 antivirus vendors with no relevant analysis report. Therefore, we think it is necessary to disclose some of its technical detail here.</p>
<p>We name it Dacls (Win32.Dacls and Linux.Dacls) based on its file name and hard-coded strings.</p>
<h2 id="daclsoverview">Dacls overview</h2>
<p>Dacls is a new type of remote-control software targeting both Windows and Linux environment. Its functions are modular, the C2 protocol uses TLS and RC4 double-layer encryption, the configuration file uses AES encryption and supports C2 instruction dynamic update. The Win32.Dacls plug-in module is dynamically loaded through a remote URL, and the Linux version of the plug-in is compiled directly in the Bot program.</p>
<h3 id="downloaderserver">Downloader server</h3>
<p>We found a series of samples on a suspected download server  <code>http://www.areac-agr.com/cms/wp-content/uploads/2015/12/</code>, including Win32.Dacls, Linux.Dacls, the open source program Socat, and working payload for Confluence CVE-2019-3396. We speculated that the Lazarus Group used the CVE-2019-3396 N-day vulnerability to spread the Dacls Bot program.</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="reverseanalysis">Reverse analysis</h2>
<h3 id="logcollectorsample">Log Collector sample</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>The function of this sample is simple. It collects the target host information by specifying the parameters of the log collecting process.  It avoids scanning some specified root and secondary directories, and write the retrieved file path to <code>/tmp/hdv.log</code>.</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>Sample logging format</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>When all the work is done, it executes the system tar command to compress the log file <code>tar -cvzf /tmp/hdv.rm /tmp/hdv.log</code> and upload it to the specified log collecting interface.</p>
<h3 id="linuxdaclssample">Linux.Dacls sample</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>The main functions of Linux.Dacls Bot include: command execution, file management, process management, test network access, C2 connection agent, network scanning module.</p>
<h4 id="initialization">Initialization</h4>
<p>After Linux.Dacls Bot is started, it runs in the daemon mode in the background, and uses the startup parameters <code>/pro</code>, the Bot PID file, <code>/var/run/init.pid</code> and the Bot process name <code>/proc/&lt;pid&gt;/cmdline</code>to distinguish different operating environments. We suspect that it may be used for Bot program upgrades.<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="configurationfilememcahce">Configuration file .memcahce</h4>
<p>The Linux.Dacls Bot configuration file is stored at <code>$HOME/.memcache</code>, and the file content is 0x8E20 + 4 bytes. If Bot cannot find the configuration file after startup, it will use AES encryption to generate the default configuration file based on the hard-coded information in the sample. After successful Bot communicates with C2, the configuration file will get updated.</p>
<h6 id="datastructure">Data structure</h6>
<p>We define the data structure information of the configuration file as struct_global_cfg, which stores the Bot operating parameters, C2 information, and plug-in information.</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="aesencryptionalgorithm">AES encryption algorithm</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="decryptingtheconfigurationfile">Decrypting the configuration file</h6>
<p>After decrypting the configuration file, we can see some plain text information in it, for example: session ID, version information, reconnection time for C2, C2 information, etc. After successfully connecting to C2, the configuration file will be updated according to received C2 instructions, such as adding new plugin information supported by the Bot, updated C2 information, etc.<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="c2protocol">C2 protocol</h4>
<p>Linux.Dacls Bot and C2 communication is mainly divided into three stages, and uses TLS and RC4 double-layer encryption algorithms to ensure data communication security. The first phase is to establish a TLS connection, the second phase is to establish agreement for authentication process (Malware Beaconing), and the third phase is to send RC4 encrypted data by Bot.</p>
<h6 id="sslconnection">SSL connection</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="phase2">Phase 2</h6>
<p>Several Beacon messages and C2 confirm each other's identity are exchanged here.</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="rc4encryptionanddecryptionprocess">RC4 encryption and decryption process</h6>
<ul>
<li>
<p>RC4 Key generation algorithm, generated by random function, Key length range: greater than 0 and less than 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>Replacement table generation algorithm, generate replacement table for RC4 encryption based on RC4 Key<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>Encryption / decryption algorithm, complete encryption / decryption according to the replacement table generation algorithm. Because RC4 is a symmetric encryption algorithm, the encryption / decryption algorithm is consistent<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 decryption example<br>
After completing the protocol authentication, Bot sends the RC4 Key length (the first 4 bytes) and RC4 Key data to C2.<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 receives the encryption key and sends the ciphertext to Bot. After decryption, the command is 0x00000700. After that, Bot will upload the hostname-related information to 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 

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

Plaintext:
00 07 00 00 00 00 00 00  00 00 00 00 
</code></pre>
<h6 id="c2instructioncodetable">C2 instruction code table</h6>
<p>The instructions accepted by Linux.Dacls Bot are a total of 12 bytes, but the actual effective size is 4 bytes, and it is divided into two control modes.</p>
<p>The first mode: when the third byte is 0, this is to control the Bot main logic.</p>
<p>The following is an example of the network sequence data packet corresponding to the 0x00000700 instruction: the mode is 0x00, and the instruction 2 is 0x07 to control Bot to upload host name information</p>
<table>
<thead>
<tr>
<th>INSTRUCTION 1</th>
<th>INSTRUCTION 2</th>
<th>MODE</th>
<th>UNKNOWN</th>
</tr>
</thead>
<tbody>
<tr>
<td>00</td>
<td>07</td>
<td>00</td>
<td>00</td>
</tr>
</tbody>
</table>
<p>The second mode: when the third byte is 1, the plug-in logic is called.</p>
<p>The following is an example of the network sequence data packet corresponding to the 0x00010101 instruction: the mode is 0x01, and the instruction 1 is 0x01.</p>
<table>
<thead>
<tr>
<th>INSTRUCTION 1</th>
<th>INSTRUCTION 2</th>
<th>MODE</th>
<th>UNKNOWN</th>
</tr>
</thead>
<tbody>
<tr>
<td>01</td>
<td>01</td>
<td>01</td>
<td>00</td>
</tr>
</tbody>
</table>
<p>After receiving the instruction, Bot returns 0x20500 on successful execution and 0x20600 on failure.</p>
<ul>
<li>C2 instruction list for the Bot main logic part</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>Upload C2 configuration information</td>
</tr>
<tr>
<td>Core</td>
<td>0x00000602</td>
<td>Yes</td>
<td>Download configuration information to  <code>$HOME/.memcache</code></td>
</tr>
<tr>
<td>Core</td>
<td>0x00000700</td>
<td>Yes</td>
<td>Ask Bot to upload host information</td>
</tr>
<tr>
<td>Core</td>
<td>0x00000900</td>
<td>Yes</td>
<td>Ask Bot to send heartbeat information</td>
</tr>
</tbody>
</table>
<ul>
<li>C2 instruction list for the Bot plugin logic</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>Execute the bash command issued by C2</td>
</tr>
<tr>
<td style="text-align:center">/bin/bash</td>
<td>0x00010002</td>
<td>Yes</td>
<td>Connect to the specified C2 and execute the issued system command</td>
</tr>
<tr>
<td style="text-align:center">plugin_file</td>
<td>0x00010100</td>
<td>Yes</td>
<td>Write file</td>
</tr>
<tr>
<td style="text-align:center">plugin_file</td>
<td>0x00010101</td>
<td>Yes</td>
<td>Read file</td>
</tr>
<tr>
<td style="text-align:center">plugin_file</td>
<td>0x00010103</td>
<td>Yes</td>
<td>Delete Files</td>
</tr>
<tr>
<td style="text-align:center">plugin_file</td>
<td>0x00010104</td>
<td>Yes</td>
<td>Scanning the directory structure</td>
</tr>
<tr>
<td style="text-align:center">plugin_file</td>
<td>0x00010110</td>
<td>Yes</td>
<td>Download file from specified url</td>
</tr>
<tr>
<td style="text-align:center">plugin_process</td>
<td>0x00010200</td>
<td>Yes</td>
<td>Scan and upload information about the host process</td>
</tr>
<tr>
<td style="text-align:center">plugin_process</td>
<td>0x00010201</td>
<td>Yes</td>
<td>Kill specified process</td>
</tr>
<tr>
<td style="text-align:center">plugin_process</td>
<td>0x00010202</td>
<td>Yes</td>
<td>Create a daemon process</td>
</tr>
<tr>
<td style="text-align:center">plugin_process</td>
<td>0x00010204</td>
<td>Yes</td>
<td>Obtain and report process PID and PPID</td>
</tr>
<tr>
<td style="text-align:center">plugin_test</td>
<td>0x00010300</td>
<td>Yes</td>
<td>Test whether the specified IP can be reached</td>
</tr>
<tr>
<td style="text-align:center">plugin_reverse_p2p</td>
<td>0x00010400</td>
<td>Yes</td>
<td>C2 Connection proxy</td>
</tr>
<tr>
<td style="text-align:center">logsend</td>
<td>0x00011100</td>
<td>Yes</td>
<td>Test if the Log server can be accessed</td>
</tr>
<tr>
<td style="text-align:center">logsend</td>
<td>0x00011101</td>
<td>Yes</td>
<td>Upload public network port scan results and command execution output</td>
</tr>
<tr>
<td style="text-align:center">logsend</td>
<td>0x00011102</td>
<td>Yes</td>
<td>No operation</td>
</tr>
</tbody>
</table>
<ul>
<li>C2 communication flowchart<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="pluginmodule">Plug-in module</h4>
<p>Linux.Dacls Bot uses static compilation to compile the plug-in and Bot code together. By sending different instructions to call different plug-ins, various tasks can be completed. The sample we analyzed contains a total of 6 plugins, because the configuration information of the plugin is a continuous array of structures (0x00 ~ 0x0e). We guess that Bot may have other more plugins.<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>Each plug-in has its own corresponding configuration, which is saved in the bot’s configuration file <code>$HOME/.memcache</code>. When the plug-in is initialized, the configuration information will be loaded.</p>
<h6 id="bashplugin">Bash plugin</h6>
<p>The Bash plug-in is plug-in number 0, it mainly supports two functions: receiving and executing system commands issued by the C2 server; C2 issues temporary new C2, bot then connects to the temporary C2 and executes system commands issued by the temporary 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="fileplugin">File plugin</h6>
<p>The main function of the File plugin is file management. In addition to supporting read, write, delete, and find operations on files, bot can also download files from a designated download server.<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="processplugin">Process plugin</h6>
<p>The main function is process management, including: killing a specified process, creating a daemon process, obtaining the PID and PPID of the current process, and obtaining process list information.<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>If the <code>/proc/&lt;pid&gt;/task</code>directory corresponding to the PID in the Linux process exists, the Bot sample will collect the following process information:</p>
<ul>
<li><code>/proc/&lt;pid&gt;/cmdline</code> Read full name from command line</li>
<li>From <code>/proc/&lt;pid&gt;/status</code> reading:</li>
</ul>
<pre><code>Name      //process name
Uid       //user ID
Gid       //group ID
PPid      //parent ID
</code></pre>
<h6 id="testplugin">Test plugin</h6>
<p>The main function is to test network connectivity by connecting the IP address and port specified by C2.<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="reversep2pplugin">Reverse P2P plugin</h6>
<p>The Reverse P2P plug-in is actually a C2 Connection Proxy, it<br>
directs network traffic between bots and C2 to avoid direct connections to their infrastructure. This is a common used technique by the Lazarus Group. With connection proxy, the number of target host connections can be reduced, and the communication between the target and the real C2 can be hidden. In some cases, an infected intranet host can be used to  further penetrates into the isolated network segment.</p>
<p>reverse_p2p plugin initialization<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>When Bot receives a command, it first attempts to connect to the specified C2 port to send a 0x21000. If C2 returns 0x21300, the C2 connection is successful and the Bot will connect to the target IP:port. If it works, it will return 0x21100 to C2, indicating that the forwarding connection has been established and can start forwarding data. Now, Bot can forward the data sent by C2 to the target, and at the same time return the data returned by the target to C2, until either party interrupts the connection.</p>
<p>The following is the working flowchart of the Reverse P2P plugin:<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="logsendplugin">LogSend plugin</h6>
<p>The LogSend plug-in mainly includes three functions: test the connection to the Log server, randomly scan the entire network's 8291 port and report to the Log server, execute system commands that take a long time and report the console output to the Log server in real time.</p>
<p>LogSend plugin initialization<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 related operation callback function<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>After testing the connection to the Log server, the<br>
Bot will send a test request to the Log server. If the Log server returns <code>{&quot;result&quot;:&quot;ok&quot;}</code>, indicating that the test was successful, C2 can issue more LogSend instructions.</p>
<p>Sending the POST request using the HTTP interface address specified by C2 and the built-in User-Agent</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>Randomly scan port 8291 on the entire network and report the result to the Log server.</p>
<p>After receiving the instruction, Bot will randomly generate a public IP address according to 3 built-in rules and try to connect to their port 8291. If the connection is successful, the scan result will be returned to the log server.</p>
<p>IP generation rules:</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>The random IP generation algorithm is as follows<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>We can see that Bot hard-codes the TCP / 8291 port and calls the system connect function to perform port scan. It only checks whether the port is open and does not send payload data. We are not sure why TCP 8291 is targeted, but we know that the Winbox protocol of the MikroTik Router device works on TCP / 8291 port and is exposed on the Internet. Previously we also disclosed 2 articles about the TCP / 8291 port threat incident <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>Execute bash command which takes a long time to finish and report the console output to the Log server in real time.<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>Execute the bash command and forward the output to the Log server.<br>
All reported Log data is submitted by HTTP POST. The format of the payload section is as follows:<br>
<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="suggestions">Suggestions</h3>
<p>We recommend that Confluence users patch their system in a timely manner and check whether they have been infected based on the process name, file name, and TCP network connection used by Dacls RAT.</p>
<p>We recommend that readers monitor and block Dacls RAT-related IPs, URLs and domain names.</p>
<h3 id="contactus">Contact us</h3>
<p>Readers are always welcomed to reach us on <a href="https://twitter.com/360Netlab"><strong>twitter</strong></a>, WeChat 360Netlab or email to netlab at 360 dot cn.</p>
<h4 id="ioclist">IoC list</h4>
<p>Sample MD5</p>
<pre><code>6de65fc57a4428ad7e262e980a7f6cc7
80c0efb9e129f7f9b05a783df6959812
982bf527b9fe16205fea606d1beed7fa
8910bdaaa6d3d40e9f60523d3a34f914
a99b7ef095f44cf35453465c64f0c70c
bea49839390e4f1eb3cb38d0fcaf897e
cef99063e85af8b065de0ffa9d26cb03
e883bf5fd22eb6237eb84d80bbcf2ac9
</code></pre>
<p>Hard-coded 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-->
Background


On October 25, 2019, a suspicious ELF file (80c0efb9e129f7f9b05a783df6959812) was flagged by our new threat monitoring system. At first glance, it seems to be just another one of the regular botnets, but we soon realized this is something with potential link to the Lazarus Group.


At present, the industry has never disclosed the Lazarus Group's attack samples and cases against the Linux platform. And our analysis shows that this is a fully functional, covert and RAT program targeting both Windows and Linux platforms, and the samples share some key characters being used by Lazarus Group.



The links between Lazarus Group and Dacls RAT


First, we searched VT for the hardcoded string c_2910.cls and k_3872.cls in the sample and found 5 more samples. We can confirm from their sample and C2 instruction codes that they are the same RAT family, and is suitable for Windows and Linux platforms, respectively.


One of the 5 samples 6de65fc57a4428ad7e262e980a7f6cc7 was pointed to as Lazarus Group by the user Raeezabdulla of the VirusTotal community, and cited a report "CES Themed Targeting from Lazarus". This sample also has download address of https://thevagabondsatchel.com/wp-content/uploads/2019/03/wm64.avi. In October 2019, a sample named NukeSped was tagged by Twitter user @cyberwar_15 as Lazarus Group. And that sample file b578ccf307d55d3267f98349e20ecff1 has the download url as http://thevagabondsatchel.com/wp-content/uploads/2019/09/public.avi


A quick google returns many Lazarus Group analysis reports and some open source threat intelligence data, many pointing out that thevagabondsatchel.com was used by Lazarus Group to store samples.


Therefore, we speculate that the attacker behind Dacls RAT is Lazarus Group.




Currently this sample is shown on VirusTotal with 26 pretty generic malware tag from by 26 antivirus vendors with no relevant analysis report. Therefore, we think it is necessary to disclose some of its technical detail here.


We name it Dacls (Win32.Dacls and Linux.Dacls) based on its file name and hard-coded strings.



Dacls overview


Dacls is a new type of remote-control software targeting both Windows and Linux environment. Its functions are modular, the C2 protocol uses TLS and RC4 double-layer encryption, the configuration file uses AES encryption and supports C2 instruction dynamic update. The Win32.Dacls plug-in module is dynamically loaded through a remote URL, and the Linux version of the plug-in is compiled directly in the Bot program.



Downloader server


We found a series of samples on a suspected download server http://www.areac-agr.com/cms/wp-content/uploads/2015/12/, including Win32.Dacls, Linux.Dacls, the open source program Socat, and working payload for Confluence CVE-2019-3396. We speculated that the Lazarus Group used the CVE-2019-3396 N-day vulnerability to spread the Dacls Bot program.


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




Reverse analysis



Log Collector sample


 * MD5: 982bf527b9fe16205fea606d1beed7fa





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



The function of this sample is simple. It collects the target host information by specifying the parameters of the log collecting process. It avoids scanning some specified root and secondary directories, and write the retrieved file path to /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



Sample logging format


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
....



When all the work is done, it executes the system tar command to compress the log file tar -cvzf /tmp/hdv.rm /tmp/hdv.log and upload it to the specified log collecting interface.



Linux.Dacls sample


 * 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



The main functions of Linux.Dacls Bot include: command execution, file management, process management, test network access, C2 connection agent, network scanning module.


Initialization


After Linux.Dacls Bot is started, it runs in the daemon mode in the background, and uses the startup parameters /pro, the Bot PID file, /var/run/init.pid and the Bot process name /proc/<pid>/cmdlineto distinguish different operating environments. We suspect that it may be used for Bot program upgrades.




Configuration file .memcahce


The Linux.Dacls Bot configuration file is stored at $HOME/.memcache, and the file content is 0x8E20 + 4 bytes. If Bot cannot find the configuration file after startup, it will use AES encryption to generate the default configuration file based on the hard-coded information in the sample. After successful Bot communicates with C2, the configuration file will get updated.


Data structure


We define the data structure information of the configuration file as struct_global_cfg, which stores the Bot operating parameters, C2 information, and plug-in information.


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 encryption algorithm


 * 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


Decrypting the configuration file


After decrypting the configuration file, we can see some plain text information in it, for example: session ID, version information, reconnection time for C2, C2 information, etc. After successfully connecting to C2, the configuration file will be updated according to received C2 instructions, such as adding new plugin information supported by the Bot, updated C2 information, etc.




C2 protocol


Linux.Dacls Bot and C2 communication is mainly divided into three stages, and uses TLS and RC4 double-layer encryption algorithms to ensure data communication security. The first phase is to establish a TLS connection, the second phase is to establish agreement for authentication process (Malware Beaconing), and the third phase is to send RC4 encrypted data by Bot.


SSL connection





Phase 2


Several Beacon messages and C2 confirm each other's identity are exchanged here.





Cmd
Direction
Encrypted
Description




0x20000
send
no
Beacon


0x20100
recv
no
Beacon


0x20200
send
no
Beacon





RC4 encryption and decryption process


 * 
   
   
   RC4 Key generation algorithm, generated by random function, Key length range: greater than 0 and less than 50
   
   
   

 * 
   
   
   Replacement table generation algorithm, generate replacement table for RC4 encryption based on RC4 Key
   
   
   

 * 
   
   
   Encryption / decryption algorithm, complete encryption / decryption according to the replacement table generation algorithm. Because RC4 is a symmetric encryption algorithm, the encryption / decryption algorithm is consistent
   
   
   

 * 
   
   
   RC4 decryption example
   
   After completing the protocol authentication, Bot sends the RC4 Key length (the first 4 bytes) and RC4 Key data to C2.
   
   
   


C2 receives the encryption key and sends the ciphertext to Bot. After decryption, the command is 0x00000700. After that, Bot will upload the hostname-related information to 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 

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

Plaintext:
00 07 00 00 00 00 00 00  00 00 00 00 



C2 instruction code table


The instructions accepted by Linux.Dacls Bot are a total of 12 bytes, but the actual effective size is 4 bytes, and it is divided into two control modes.


The first mode: when the third byte is 0, this is to control the Bot main logic.


The following is an example of the network sequence data packet corresponding to the 0x00000700 instruction: the mode is 0x00, and the instruction 2 is 0x07 to control Bot to upload host name information





INSTRUCTION 1
INSTRUCTION 2
MODE
UNKNOWN




00
07
00
00





The second mode: when the third byte is 1, the plug-in logic is called.


The following is an example of the network sequence data packet corresponding to the 0x00010101 instruction: the mode is 0x01, and the instruction 1 is 0x01.





INSTRUCTION 1
INSTRUCTION 2
MODE
UNKNOWN




01
01
01
00





After receiving the instruction, Bot returns 0x20500 on successful execution and 0x20600 on failure.


 * C2 instruction list for the Bot main logic part





MODULE
CMD
ENCRYPT
Description




Core
0x00000601
Yes
Upload C2 configuration information


Core
0x00000602
Yes
Download configuration information to $HOME/.memcache


Core
0x00000700
Yes
Ask Bot to upload host information


Core
0x00000900
Yes
Ask Bot to send heartbeat information





 * C2 instruction list for the Bot plugin logic





MODULE
CMD
ENCRYPT
Description




/bin/bash
0x00010000
Yes
Execute the bash command issued by C2


/bin/bash
0x00010002
Yes
Connect to the specified C2 and execute the issued system command


plugin_file
0x00010100
Yes
Write file


plugin_file
0x00010101
Yes
Read file


plugin_file
0x00010103
Yes
Delete Files


plugin_file
0x00010104
Yes
Scanning the directory structure


plugin_file
0x00010110
Yes
Download file from specified url


plugin_process
0x00010200
Yes
Scan and upload information about the host process


plugin_process
0x00010201
Yes
Kill specified process


plugin_process
0x00010202
Yes
Create a daemon process


plugin_process
0x00010204
Yes
Obtain and report process PID and PPID


plugin_test
0x00010300
Yes
Test whether the specified IP can be reached


plugin_reverse_p2p
0x00010400
Yes
C2 Connection proxy


logsend
0x00011100
Yes
Test if the Log server can be accessed


logsend
0x00011101
Yes
Upload public network port scan results and command execution output


logsend
0x00011102
Yes
No operation





 * C2 communication flowchart
   
   


Plug-in module


Linux.Dacls Bot uses static compilation to compile the plug-in and Bot code together. By sending different instructions to call different plug-ins, various tasks can be completed. The sample we analyzed contains a total of 6 plugins, because the configuration information of the plugin is a continuous array of structures (0x00 ~ 0x0e). We guess that Bot may have other more plugins.




Each plug-in has its own corresponding configuration, which is saved in the bot’s configuration file $HOME/.memcache. When the plug-in is initialized, the configuration information will be loaded.


Bash plugin


The Bash plug-in is plug-in number 0, it mainly supports two functions: receiving and executing system commands issued by the C2 server; C2 issues temporary new C2, bot then connects to the temporary C2 and executes system commands issued by the temporary C2.




File plugin


The main function of the File plugin is file management. In addition to supporting read, write, delete, and find operations on files, bot can also download files from a designated download server.




Process plugin


The main function is process management, including: killing a specified process, creating a daemon process, obtaining the PID and PPID of the current process, and obtaining process list information.




If the /proc/<pid>/taskdirectory corresponding to the PID in the Linux process exists, the Bot sample will collect the following process information:


 * /proc/<pid>/cmdline Read full name from command line
 * From /proc/<pid>/status reading:


Name      //process name
Uid       //user ID
Gid       //group ID
PPid      //parent ID



Test plugin


The main function is to test network connectivity by connecting the IP address and port specified by C2.




Reverse P2P plugin


The Reverse P2P plug-in is actually a C2 Connection Proxy, it

directs network traffic between bots and C2 to avoid direct connections to their infrastructure. This is a common used technique by the Lazarus Group. With connection proxy, the number of target host connections can be reduced, and the communication between the target and the real C2 can be hidden. In some cases, an infected intranet host can be used to further penetrates into the isolated network segment.


reverse_p2p plugin initialization




When Bot receives a command, it first attempts to connect to the specified C2 port to send a 0x21000. If C2 returns 0x21300, the C2 connection is successful and the Bot will connect to the target IP:port. If it works, it will return 0x21100 to C2, indicating that the forwarding connection has been established and can start forwarding data. Now, Bot can forward the data sent by C2 to the target, and at the same time return the data returned by the target to C2, until either party interrupts the connection.


The following is the working flowchart of the Reverse P2P plugin:




LogSend plugin


The LogSend plug-in mainly includes three functions: test the connection to the Log server, randomly scan the entire network's 8291 port and report to the Log server, execute system commands that take a long time and report the console output to the Log server in real time.


LogSend plugin initialization




LogSend related operation callback function




After testing the connection to the Log server, the

Bot will send a test request to the Log server. If the Log server returns {"result":"ok"}, indicating that the test was successful, C2 can issue more LogSend instructions.


Sending the POST request using the HTTP interface address specified by C2 and the built-in User-Agent


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



Randomly scan port 8291 on the entire network and report the result to the Log server.


After receiving the instruction, Bot will randomly generate a public IP address according to 3 built-in rules and try to connect to their port 8291. If the connection is successful, the scan result will be returned to the log server.


IP generation rules:


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



The random IP generation algorithm is as follows




We can see that Bot hard-codes the TCP / 8291 port and calls the system connect function to perform port scan. It only checks whether the port is open and does not send payload data. We are not sure why TCP 8291 is targeted, but we know that the Winbox protocol of the MikroTik Router device works on TCP / 8291 port and is exposed on the Internet. Previously we also disclosed 2 articles about the TCP / 8291 port threat incident [1][2].




Execute bash command which takes a long time to finish and report the console output to the Log server in real time.




Execute the bash command and forward the output to the Log server.

All reported Log data is submitted by HTTP POST. The format of the payload section is as follows:

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





Suggestions


We recommend that Confluence users patch their system in a timely manner and check whether they have been infected based on the process name, file name, and TCP network connection used by Dacls RAT.


We recommend that readers monitor and block Dacls RAT-related IPs, URLs and domain names.



Contact us


Readers are always welcomed to reach us on twitter, WeChat 360Netlab or email to netlab at 360 dot cn.


IoC list


Sample MD5


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



Hard-coded 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":"## Background\nOn October 25, 2019, a suspicious ELF file (80c0efb9e129f7f9b05a783df6959812) was flagged by our  new threat monitoring system. At first glance, it seems to be just another one of the regular botnets, but we soon realized this is something with potential link to the Lazarus Group. \n\nAt present, the industry has never disclosed the Lazarus Group's attack samples and cases against the Linux platform. And our analysis shows that this is a fully functional, covert and RAT program targeting both Windows and Linux platforms, and the samples share some key characters being used by Lazarus Group. \n\n### The links between Lazarus Group and Dacls RAT\nFirst, we searched VT for the hardcoded string ```c_2910.cls``` and ```k_3872.cls``` in the sample and found 5 more samples. We can confirm from their sample and C2 instruction codes that they are the same RAT family, and is suitable for Windows and Linux platforms, respectively. \n\nOne of the 5 samples ```6de65fc57a4428ad7e262e980a7f6cc7``` was pointed to as Lazarus Group by the user Raeezabdulla of the VirusTotal community, and cited a report \"CES Themed Targeting from Lazarus\". This sample also has download address of ```https://thevagabondsatchel.com/wp-content/uploads/2019/03/wm64.avi```. In October 2019, a sample named NukeSped was tagged by Twitter user @cyberwar_15 as Lazarus Group. And that sample file ```b578ccf307d55d3267f98349e20ecff1``` has the download url as ```http://thevagabondsatchel.com/wp-content/uploads/2019/09/public.avi```\n\nA quick google returns many Lazarus Group analysis reports and some open source threat intelligence data, many pointing out that thevagabondsatchel.com was used by Lazarus Group to store samples.\n\nTherefore, we speculate that the attacker behind Dacls RAT is Lazarus Group.\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\nCurrently this sample is shown on VirusTotal with 26 pretty generic malware tag from by 26 antivirus vendors with no relevant analysis report. Therefore, we think it is necessary to disclose some of its technical detail here.\n\nWe name it Dacls (Win32.Dacls and Linux.Dacls) based on its file name and hard-coded strings.\n\n## Dacls overview\nDacls is a new type of remote-control software targeting both Windows and Linux environment. Its functions are modular, the C2 protocol uses TLS and RC4 double-layer encryption, the configuration file uses AES encryption and supports C2 instruction dynamic update. The Win32.Dacls plug-in module is dynamically loaded through a remote URL, and the Linux version of the plug-in is compiled directly in the Bot program. \n\n### Downloader server\nWe found a series of samples on a suspected download server  ```http://www.areac-agr.com/cms/wp-content/uploads/2015/12/```, including Win32.Dacls, Linux.Dacls, the open source program Socat, and working payload for Confluence CVE-2019-3396. We speculated that the Lazarus Group used the CVE-2019-3396 N-day vulnerability to spread the Dacls Bot program.\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## Reverse analysis\n### Log Collector sample\n- MD5: 982bf527b9fe16205fea606d1beed7fa\n> ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header\n\nThe function of this sample is simple. It collects the target host information by specifying the parameters of the log collecting process.  It avoids scanning some specified root and secondary directories, and write the retrieved file path to ```/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\nSample logging format\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\nWhen all the work is done, it executes the system tar command to compress the log file ```tar -cvzf /tmp/hdv.rm /tmp/hdv.log``` and upload it to the specified log collecting interface.\n\n### Linux.Dacls sample\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\nThe main functions of Linux.Dacls Bot include: command execution, file management, process management, test network access, C2 connection agent, network scanning module.\n\n#### Initialization\nAfter Linux.Dacls Bot is started, it runs in the daemon mode in the background, and uses the startup parameters ```/pro```, the Bot PID file, ```/var/run/init.pid``` and the Bot process name ```/proc/<pid>/cmdline```to distinguish different operating environments. We suspect that it may be used for Bot program upgrades.\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#### Configuration file .memcahce\nThe Linux.Dacls Bot configuration file is stored at ```$HOME/.memcache```, and the file content is 0x8E20 + 4 bytes. If Bot cannot find the configuration file after startup, it will use AES encryption to generate the default configuration file based on the hard-coded information in the sample. After successful Bot communicates with C2, the configuration file will get updated. \n\n###### Data structure\nWe define the data structure information of the configuration file as struct_global_cfg, which stores the Bot operating parameters, C2 information, and plug-in information.\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 encryption algorithm\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###### Decrypting the configuration file \nAfter decrypting the configuration file, we can see some plain text information in it, for example: session ID, version information, reconnection time for C2, C2 information, etc. After successfully connecting to C2, the configuration file will be updated according to received C2 instructions, such as adding new plugin information supported by the Bot, updated C2 information, etc.\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 protocol\nLinux.Dacls Bot and C2 communication is mainly divided into three stages, and uses TLS and RC4 double-layer encryption algorithms to ensure data communication security. The first phase is to establish a TLS connection, the second phase is to establish agreement for authentication process (Malware Beaconing), and the third phase is to send RC4 encrypted data by Bot.\n\n###### SSL connection\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###### Phase 2\nSeveral Beacon messages and C2 confirm each other's identity are exchanged here.\n| Cmd    | Direction             | Encrypted         | Description|\n| -----  | ------------------ | ------------ |:----------: |\n|0x20000 | send     |   no         | Beacon|\n|0x20100 | recv       | no          |Beacon|\n|0x20200 |  send       | no       |   Beacon|\n\n###### RC4 encryption and decryption process\n- RC4 Key generation algorithm, generated by random function, Key length range: greater than 0 and less than 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- Replacement table generation algorithm, generate replacement table for RC4 encryption based on RC4 Key\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- Encryption / decryption algorithm, complete encryption / decryption according to the replacement table generation algorithm. Because RC4 is a symmetric encryption algorithm, the encryption / decryption algorithm is consistent\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 decryption example\nAfter completing the protocol authentication, Bot sends the RC4 Key length (the first 4 bytes) and RC4 Key data to C2.\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 receives the encryption key and sends the ciphertext to Bot. After decryption, the command is 0x00000700. After that, Bot will upload the hostname-related information to C2.\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\nCiphertext:\nfe 3c 2c d7 bf 08 e3 91  d7 00 1f d0\n\nPlaintext:\n00 07 00 00 00 00 00 00  00 00 00 00 \n```\n###### C2 instruction code table\nThe instructions accepted by Linux.Dacls Bot are a total of 12 bytes, but the actual effective size is 4 bytes, and it is divided into two control modes.\n\nThe first mode: when the third byte is 0, this is to control the Bot main logic.\n\nThe following is an example of the network sequence data packet corresponding to the 0x00000700 instruction: the mode is 0x00, and the instruction 2 is 0x07 to control Bot to upload host name information\n|  INSTRUCTION 1 |  INSTRUCTION 2  | MODE  | UNKNOWN |\n|------ | ------ | ------ | ------|\n|  00    | 07     |00     |00     |\n\nThe second mode: when the third byte is 1, the plug-in logic is called.\n\nThe following is an example of the network sequence data packet corresponding to the 0x00010101 instruction: the mode is 0x01, and the instruction 1 is 0x01.\n|  INSTRUCTION 1 |  INSTRUCTION 2  | MODE  | UNKNOWN |\n|------ | ------ | ------ | ------|\n|  01    | 01     |01     |00     |\n\nAfter receiving the instruction, Bot returns 0x20500 on successful execution and 0x20600 on failure.\n\n- C2 instruction list for the Bot main logic part\n\n| MODULE | CMD        | ENCRYPT | Description                              |\n| ------ | ---------- | ------- | ---------------------------------------- |\n| Core   | 0x00000601 | Yes     | Upload C2 configuration information                           |\n| Core   | 0x00000602 | Yes     | Download configuration information to  ```$HOME/.memcache``` |\n| Core   | 0x00000700 | Yes     | Ask Bot to upload host information       |\n| Core   | 0x00000900 | Yes     | Ask Bot to send heartbeat information                      |\n\n- C2 instruction list for the Bot plugin logic\n\n| MODULE | CMD        | ENCRYPT | Description                        |\n| :----------------: | ---------- | ------- | ---------------------------------- |\n|     /bin/bash      | 0x00010000 | Yes     | Execute the bash command issued by C2               |\n|     /bin/bash      | 0x00010002 | Yes     | Connect to the specified C2 and execute the issued system command   |\n|    plugin_file     | 0x00010100 | Yes     | Write file                             |\n|    plugin_file     | 0x00010101 | Yes     | Read file                             |\n|    plugin_file     | 0x00010103 | Yes     | Delete Files                           |\n|    plugin_file     | 0x00010104 | Yes     | Scanning the directory structure                       |\n|    plugin_file     | 0x00010110 | Yes     | Download file from specified url                  |\n|   plugin_process   | 0x00010200 | Yes     | Scan and upload information about the host process         |\n|   plugin_process   | 0x00010201 | Yes     | Kill specified process                       |\n|   plugin_process   | 0x00010202 | Yes     | Create a daemon process                     |\n|   plugin_process   | 0x00010204 | Yes     | Obtain and report process PID and PPID            |\n|    plugin_test     | 0x00010300 | Yes     | Test whether the specified IP can be reached             |\n| plugin_reverse_p2p | 0x00010400 | Yes     | C2 Connection proxy                         |\n|      logsend       | 0x00011100 | Yes     | Test if the Log server can be accessed          |\n|      logsend       | 0x00011101 | Yes     | Upload public network port scan results and command execution output |\n|      logsend       | 0x00011102 | Yes     | No operation                             |\n\n- C2 communication flowchart\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#### Plug-in module\nLinux.Dacls Bot uses static compilation to compile the plug-in and Bot code together. By sending different instructions to call different plug-ins, various tasks can be completed. The sample we analyzed contains a total of 6 plugins, because the configuration information of the plugin is a continuous array of structures (0x00 ~ 0x0e). We guess that Bot may have other more plugins.\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\nEach plug-in has its own corresponding configuration, which is saved in the bot’s configuration file ```$HOME/.memcache```. When the plug-in is initialized, the configuration information will be loaded.\n\n###### Bash plugin\nThe Bash plug-in is plug-in number 0, it mainly supports two functions: receiving and executing system commands issued by the C2 server; C2 issues temporary new C2, bot then connects to the temporary C2 and executes system commands issued by the temporary 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 plugin\nThe main function of the File plugin is file management. In addition to supporting read, write, delete, and find operations on files, bot can also download files from a designated download server.\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 plugin\nThe main function is process management, including: killing a specified process, creating a daemon process, obtaining the PID and PPID of the current process, and obtaining process list information.\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\nIf the ```/proc/<pid>/task```directory corresponding to the PID in the Linux process exists, the Bot sample will collect the following process information:\n\n- ```/proc/<pid>/cmdline``` Read full name from command line\n- From ```/proc/<pid>/status``` reading:\n```\nName      //process name\nUid       //user ID\nGid       //group ID\nPPid      //parent ID\n```\n\n\n###### Test plugin\nThe main function is to test network connectivity by connecting the IP address and port specified by C2.\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 plugin\nThe Reverse P2P plug-in is actually a C2 Connection Proxy, it\ndirects network traffic between bots and C2 to avoid direct connections to their infrastructure. This is a common used technique by the Lazarus Group. With connection proxy, the number of target host connections can be reduced, and the communication between the target and the real C2 can be hidden. In some cases, an infected intranet host can be used to  further penetrates into the isolated network segment.\n\nreverse_p2p plugin initialization\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\nWhen Bot receives a command, it first attempts to connect to the specified C2 port to send a 0x21000. If C2 returns 0x21300, the C2 connection is successful and the Bot will connect to the target IP:port. If it works, it will return 0x21100 to C2, indicating that the forwarding connection has been established and can start forwarding data. Now, Bot can forward the data sent by C2 to the target, and at the same time return the data returned by the target to C2, until either party interrupts the connection.\n\nThe following is the working flowchart of the Reverse P2P plugin:\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 plugin\nThe LogSend plug-in mainly includes three functions: test the connection to the Log server, randomly scan the entire network's 8291 port and report to the Log server, execute system commands that take a long time and report the console output to the Log server in real time.\n\nLogSend plugin initialization\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 related operation callback function\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\nAfter testing the connection to the Log server, the\nBot will send a test request to the Log server. If the Log server returns ```{\"result\":\"ok\"}```, indicating that the test was successful, C2 can issue more LogSend instructions.\n\nSending the POST request using the HTTP interface address specified by C2 and the built-in User-Agent\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```\nRandomly scan port 8291 on the entire network and report the result to the Log server.\n\nAfter receiving the instruction, Bot will randomly generate a public IP address according to 3 built-in rules and try to connect to their port 8291. If the connection is successful, the scan result will be returned to the log server.\n\nIP generation rules:\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```\nThe random IP generation algorithm is as follows\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\nWe can see that Bot hard-codes the TCP / 8291 port and calls the system connect function to perform port scan. It only checks whether the port is open and does not send payload data. We are not sure why TCP 8291 is targeted, but we know that the Winbox protocol of the MikroTik Router device works on TCP / 8291 port and is exposed on the Internet. Previously we also disclosed 2 articles about the TCP / 8291 port threat incident [\\[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\nExecute bash command which takes a long time to finish and report the console output to the Log server in real time.\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\nExecute the bash command and forward the output to the Log server.\nAll reported Log data is submitted by HTTP POST. The format of the payload section is as follows:\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### Suggestions\nWe recommend that Confluence users patch their system in a timely manner and check whether they have been infected based on the process name, file name, and TCP network connection used by Dacls RAT.\n\nWe recommend that readers monitor and block Dacls RAT-related IPs, URLs and domain names.\n\n### Contact us\nReaders are always welcomed to reach us on [**twitter**](https://twitter.com/360Netlab), WeChat 360Netlab or email to netlab at 360 dot cn.\n\n\n\n\n#### IoC list\nSample MD5\n```\n6de65fc57a4428ad7e262e980a7f6cc7\n80c0efb9e129f7f9b05a783df6959812\n982bf527b9fe16205fea606d1beed7fa\n8910bdaaa6d3d40e9f60523d3a34f914\na99b7ef095f44cf35453465c64f0c70c\nbea49839390e4f1eb3cb38d0fcaf897e\ncef99063e85af8b065de0ffa9d26cb03\ne883bf5fd22eb6237eb84d80bbcf2ac9\n```\n\nHard-coded 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"}