RotaJakiro, the Linux version of the OceanLotus
<!--kg-card-begin: markdown--><p>On Apr 28, we published our <a href="__GHOST_URL__/stealth_rotajakiro_backdoor_en/"><strong>RotaJakiro</strong></a> backdoor blog, at that time, we didn’t have the answer for a very important question, what is this backdoor exactly for? We asked the community for clues and two days ago we got a hint, <code>PE</code>(Thanks!) wrote the following comment on our blog post.<br>
<img src="__GHOST_URL__/content/images/2021/05/--.png" width="860px"  /><br>
The <a href="https://www.virustotal.com/gui/file/b33370167853330704945684c50ce0af6eb27838e1e3f88ea457d2c88a223d8b/detection">sample</a> mentioned in the message is a zip packing file, which has appeared in 2016. The zip contains multiple files, the Mach-O format executable file named <code>Noi dung chi tiet</code> (translated to <code>detailed information</code>) is the OceanLotus sample. When we compare the this file with the RotaJakiro sample, we noticed there are multiple similarities and it is <code>VERY likely</code> that this is <strong>the Linux version of the OceanLotus</strong>.</p>
<h2 id="similarity1functionforc2sessioncreation">Similarity 1: Function for C2 session creation</h2>
<p>The common domain name resolution function for Linux is <code>gethostbyname()</code>, but RotaJakiro uses the relatively niche <code>getaddrinfo()</code> function. C2 domain name resolution and session establishment are performed in one function, this is also used by the the OceanLotus sample. The comparison of the 2 functions is as follows.<br>
<img src="__GHOST_URL__/content/images/2021/05/init_c2_session_comparison.png" width="860px"  /><br>
It can be seen that they not only have the same function, but also use <code>sprintf() and getaddrinfo()</code> in almost exactly the same way. In addition, both RotaJakiro and OceanLotus use separate data structures to hold C2 session information, such as <code>socket fd, whether active, timeout</code>, etc., and their data structures are also very similar.<br>
<img src="__GHOST_URL__/content/images/2021/05/c2confcmp.png" width="860px" /></p>
<h2 id="similarity2registrationpacketconstructionmethod">Similarity 2: registration packet construction method</h2>
<p>The network packets of both RotaJakiro and OceanLotus are composed of<code> Head, Key, and Payload</code>, of which Head is mandatory and has a length of 82 bytes, while Key and Payload are optional.</p>
<ul>
<li>Offset 1, type DWORD, which holds a magic.</li>
<li>Offset 9, type DWORD, holding the length of the Payload.</li>
<li>Offset 13, type WORD, holding the Key length.</li>
<li>Offset 15, type DWORD, holds the message code.</li>
</ul>
<p>The RotaJakiro initializes the Head of the registration packets with a separate function.<br>
<img src="__GHOST_URL__/content/images/2021/05/register_init_rota-1.png" alt="register_init_rota-1" loading="lazy"><br>
This function first calls the malloc() function to dynamically allocate memory for the registrationpacket, then calls the time()/srand()/rand() function in turn to generate a random character and then assign it to the first field of the registration packet, and the remaining large swath of code is to assign values to the remaining fields one by one with multiple constants, so the most obvious feature of this function is to <code>initialize the registration packet with multiple constants</code>.<br>
There is also a function in the OceanLotus sample that is dedicated to initializing the Head of the registration packets.<br>
<img src="__GHOST_URL__/content/images/2021/05/register_init_ocean.png" alt="register_init_ocean" loading="lazy"><br>
This function has no code for memory allocation and random character generation, and the whole function uses multiple constants to assign values to specific fields of the registration packet one by one, <code>exactly like the RotaJakiro</code>. In addition, OceanLotus shares the same field values with RotaJakiro at offsets 1, 24 and 75, especially the magic at offset 1 is <code>0x3B91011</code>, which is hard to describe as a coincidence, so it greatly increases the probability that these two pieces of code are the same origin. In addition, both the RotaJakiro and the OceanLotus have assigned message codes to the registration packets, and both are <code>0x2170272</code>:<br>
<img src="__GHOST_URL__/content/images/2021/05/regpkgcmp.png" width="860px" /><br>
The resulting registration packets is also very similar, and the RotaJakiro registration packets is as follows.<br>
<img src="__GHOST_URL__/content/images/2021/05/regcmp_rota.png" width="724px" /><br>
The following is the OceanLotus registration packets analyzed by <a href="https://unit42.paloaltonetworks.com/unit42-new-improved-macos-backdoor-oceanlotus/">PAN</a> in 2017.<br>
<img src="__GHOST_URL__/content/images/2021/05/regcmp_ocean.png" alt="regcmp_ocean" loading="lazy"><br>
The decrypted registration packets for the RotaJakiro is shown below.<br>
<img src="__GHOST_URL__/content/images/2021/05/pkgcmd_rota.png" width="834px" /><br>
The following is the OceanLotus plaintext registration packets from <a href="https://unit42.paloaltonetworks.com/unit42-new-improved-macos-backdoor-oceanlotus/">PAN</a>'s analysis.<br>
<img src="__GHOST_URL__/content/images/2021/05/pkgcmp_ocean.png" alt="pkgcmp_ocean" loading="lazy"><br>
You can see that they have the same plaintext structure and basically the same key field values.</p>
<h2 id="similarity3rotatefunction">Similarity 3: rotate function</h2>
<p>Both RotaJakiro and OceanLotus have a function we called <code>rotate()</code> for encryption/decryption, the rotate function of RotaJakiro is as follows.<br>
<img src="__GHOST_URL__/content/images/2021/05/rotate_rota.png" alt="rotate_rota" loading="lazy"><br>
For OceanLotus<br>
<img src="__GHOST_URL__/content/images/2021/05/rotate_ocea.png" alt="rotate_ocea" loading="lazy"><br>
It is easy to see the commonalities between them.</p>
<ol>
<li>Both accept 3 parameters.</li>
<li>The prototype is the same, where the first parameter is the actual rotate object, the second parameter is the length field, and the third parameter plays a control role.</li>
</ol>
<p>In actual use, for example, in the process of encrypting the registration packets, you can see that the RotaJakiro and the OceanLotus <code>use the same parameters</code>.<br>
<img src="__GHOST_URL__/content/images/2021/05/rotatecmp.png" width="860px" /></p>
<h2 id="similarity4sameinstructioncode">Similarity 4: Same instruction code</h2>
<p>Both RotaJakiro and OceanLotus  use DWORD type instruction codes to specify the function of the message, and share several semantically identical instruction codes, some of which are featured as shown in the following table.</p>
<table>
<thead>
<tr>
<th>Cmd</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x18320e0</td>
<td>Upload device Info</td>
</tr>
<tr>
<td>0x2170272</td>
<td>Register</td>
</tr>
<tr>
<td>0x1B25503</td>
<td>execute function from a plugin(a aynamic library)</td>
</tr>
<tr>
<td>0x1532e65</td>
<td>execute function from a plugin(a aynamic library)</td>
</tr>
<tr>
<td>0x25D5082</td>
<td>execute function from a plugin(a aynamic library)</td>
</tr>
<tr>
<td>This similarity obviously cannot be explained by coincidence, <strong>it is an extremely strong evidence of their code homology</strong>.</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="summary">Summary</h2>
<p>Although the RotaJakiro and the Mac version of the OceanLotus are implemented in different languages, their similarity in function and message format design, and their similarity in specific implementation, can no longer be explained by coincidence. <strong>It is highly likely that RotaJakiro is a Linux version of the OceanLotus.</strong></p>
<!--kg-card-end: markdown-->
On Apr 28, we published our RotaJakiro backdoor blog, at that time, we didn’t have the answer for a very important question, what is this backdoor exactly for? We asked the community for clues and two days ago we got a hint, PE(Thanks!) wrote the following comment on our blog post.



The sample mentioned in the message is a zip packing file, which has appeared in 2016. The zip contains multiple files, the Mach-O format executable file named Noi dung chi tiet (translated to detailed information) is the OceanLotus sample. When we compare the this file with the RotaJakiro sample, we noticed there are multiple similarities and it is VERY likely that this is the Linux version of the OceanLotus.



Similarity 1: Function for C2 session creation


The common domain name resolution function for Linux is gethostbyname(), but RotaJakiro uses the relatively niche getaddrinfo() function. C2 domain name resolution and session establishment are performed in one function, this is also used by the the OceanLotus sample. The comparison of the 2 functions is as follows.



It can be seen that they not only have the same function, but also use sprintf() and getaddrinfo() in almost exactly the same way. In addition, both RotaJakiro and OceanLotus use separate data structures to hold C2 session information, such as socket fd, whether active, timeout, etc., and their data structures are also very similar.





Similarity 2: registration packet construction method


The network packets of both RotaJakiro and OceanLotus are composed of Head, Key, and Payload, of which Head is mandatory and has a length of 82 bytes, while Key and Payload are optional.


 * Offset 1, type DWORD, which holds a magic.
 * Offset 9, type DWORD, holding the length of the Payload.
 * Offset 13, type WORD, holding the Key length.
 * Offset 15, type DWORD, holds the message code.


The RotaJakiro initializes the Head of the registration packets with a separate function.



This function first calls the malloc() function to dynamically allocate memory for the registrationpacket, then calls the time()/srand()/rand() function in turn to generate a random character and then assign it to the first field of the registration packet, and the remaining large swath of code is to assign values to the remaining fields one by one with multiple constants, so the most obvious feature of this function is to initialize the registration packet with multiple constants.

There is also a function in the OceanLotus sample that is dedicated to initializing the Head of the registration packets.



This function has no code for memory allocation and random character generation, and the whole function uses multiple constants to assign values to specific fields of the registration packet one by one, exactly like the RotaJakiro. In addition, OceanLotus shares the same field values with RotaJakiro at offsets 1, 24 and 75, especially the magic at offset 1 is 0x3B91011, which is hard to describe as a coincidence, so it greatly increases the probability that these two pieces of code are the same origin. In addition, both the RotaJakiro and the OceanLotus have assigned message codes to the registration packets, and both are 0x2170272:



The resulting registration packets is also very similar, and the RotaJakiro registration packets is as follows.



The following is the OceanLotus registration packets analyzed by PAN in 2017.



The decrypted registration packets for the RotaJakiro is shown below.



The following is the OceanLotus plaintext registration packets from PAN's analysis.



You can see that they have the same plaintext structure and basically the same key field values.



Similarity 3: rotate function


Both RotaJakiro and OceanLotus have a function we called rotate() for encryption/decryption, the rotate function of RotaJakiro is as follows.



For OceanLotus



It is easy to see the commonalities between them.


 1. Both accept 3 parameters.
 2. The prototype is the same, where the first parameter is the actual rotate object, the second parameter is the length field, and the third parameter plays a control role.


In actual use, for example, in the process of encrypting the registration packets, you can see that the RotaJakiro and the OceanLotus use the same parameters.





Similarity 4: Same instruction code


Both RotaJakiro and OceanLotus use DWORD type instruction codes to specify the function of the message, and share several semantically identical instruction codes, some of which are featured as shown in the following table.





Cmd
Function




0x18320e0
Upload device Info


0x2170272
Register


0x1B25503
execute function from a plugin(a aynamic library)


0x1532e65
execute function from a plugin(a aynamic library)


0x25D5082
execute function from a plugin(a aynamic library)


This similarity obviously cannot be explained by coincidence, it is an extremely strong evidence of their code homology.







Summary


Although the RotaJakiro and the Mac version of the OceanLotus are implemented in different languages, their similarity in function and message format design, and their similarity in specific implementation, can no longer be explained by coincidence. It is highly likely that RotaJakiro is a Linux version of the OceanLotus.

{"version":"0.3.1","atoms":[],"cards":[["markdown",{"markdown":"On Apr 28, we published our [**RotaJakiro**](__GHOST_URL__/stealth_rotajakiro_backdoor_en/) backdoor blog, at that time, we didn’t have the answer for a very important question, what is this backdoor exactly for? We asked the community for clues and two days ago we got a hint, ```PE```(Thanks!) wrote the following comment on our blog post.\n<img src=\"__GHOST_URL__/content/images/2021/05/--.png\" width=\"860px\"  />\nThe [sample](https://www.virustotal.com/gui/file/b33370167853330704945684c50ce0af6eb27838e1e3f88ea457d2c88a223d8b/detection) mentioned in the message is a zip packing file, which has appeared in 2016. The zip contains multiple files, the Mach-O format executable file named ```Noi dung chi tiet``` (translated to ```detailed information```) is the OceanLotus sample. When we compare the this file with the RotaJakiro sample, we noticed there are multiple similarities and it is ```VERY likely``` that this is **the Linux version of the OceanLotus**.\n## Similarity 1: Function for C2 session creation\nThe common domain name resolution function for Linux is ```gethostbyname()```, but RotaJakiro uses the relatively niche ```getaddrinfo()``` function. C2 domain name resolution and session establishment are performed in one function, this is also used by the the OceanLotus sample. The comparison of the 2 functions is as follows.\n<img src=\"__GHOST_URL__/content/images/2021/05/init_c2_session_comparison.png\" width=\"860px\"  />\nIt can be seen that they not only have the same function, but also use ```sprintf() and getaddrinfo()``` in almost exactly the same way. In addition, both RotaJakiro and OceanLotus use separate data structures to hold C2 session information, such as ```socket fd, whether active, timeout```, etc., and their data structures are also very similar.\n<img src=\"__GHOST_URL__/content/images/2021/05/c2confcmp.png\" width=\"860px\" />\n## Similarity 2: registration packet construction method\nThe network packets of both RotaJakiro and OceanLotus are composed of``` Head, Key, and Payload```, of which Head is mandatory and has a length of 82 bytes, while Key and Payload are optional.\n- Offset 1, type DWORD, which holds a magic.\n- Offset 9, type DWORD, holding the length of the Payload.\n- Offset 13, type WORD, holding the Key length.\n- Offset 15, type DWORD, holds the message code.\n\nThe RotaJakiro initializes the Head of the registration packets with a separate function.\n![register_init_rota-1](__GHOST_URL__/content/images/2021/05/register_init_rota-1.png)\nThis function first calls the malloc() function to dynamically allocate memory for the registrationpacket, then calls the time()/srand()/rand() function in turn to generate a random character and then assign it to the first field of the registration packet, and the remaining large swath of code is to assign values to the remaining fields one by one with multiple constants, so the most obvious feature of this function is to ```initialize the registration packet with multiple constants```.\nThere is also a function in the OceanLotus sample that is dedicated to initializing the Head of the registration packets.\n![register_init_ocean](__GHOST_URL__/content/images/2021/05/register_init_ocean.png)\nThis function has no code for memory allocation and random character generation, and the whole function uses multiple constants to assign values to specific fields of the registration packet one by one, ```exactly like the RotaJakiro```. In addition, OceanLotus shares the same field values with RotaJakiro at offsets 1, 24 and 75, especially the magic at offset 1 is ```0x3B91011```, which is hard to describe as a coincidence, so it greatly increases the probability that these two pieces of code are the same origin. In addition, both the RotaJakiro and the OceanLotus have assigned message codes to the registration packets, and both are ```0x2170272```:\n<img src=\"__GHOST_URL__/content/images/2021/05/regpkgcmp.png\" width=\"860px\" />\nThe resulting registration packets is also very similar, and the RotaJakiro registration packets is as follows.\n<img src=\"__GHOST_URL__/content/images/2021/05/regcmp_rota.png\" width=\"724px\" />\nThe following is the OceanLotus registration packets analyzed by [PAN](https://unit42.paloaltonetworks.com/unit42-new-improved-macos-backdoor-oceanlotus/) in 2017.\n![regcmp_ocean](__GHOST_URL__/content/images/2021/05/regcmp_ocean.png)\nThe decrypted registration packets for the RotaJakiro is shown below.\n<img src=\"__GHOST_URL__/content/images/2021/05/pkgcmd_rota.png\" width=\"834px\" />\nThe following is the OceanLotus plaintext registration packets from [PAN](https://unit42.paloaltonetworks.com/unit42-new-improved-macos-backdoor-oceanlotus/)'s analysis.\n![pkgcmp_ocean](__GHOST_URL__/content/images/2021/05/pkgcmp_ocean.png)\nYou can see that they have the same plaintext structure and basically the same key field values.\n## Similarity 3: rotate function\nBoth RotaJakiro and OceanLotus have a function we called ```rotate()``` for encryption/decryption, the rotate function of RotaJakiro is as follows.\n![rotate_rota](__GHOST_URL__/content/images/2021/05/rotate_rota.png)\nFor OceanLotus\n![rotate_ocea](__GHOST_URL__/content/images/2021/05/rotate_ocea.png)\nIt is easy to see the commonalities between them.\n 1. Both accept 3 parameters.\n 2. The prototype is the same, where the first parameter is the actual rotate object, the second parameter is the length field, and the third parameter plays a control role.\n\nIn actual use, for example, in the process of encrypting the registration packets, you can see that the RotaJakiro and the OceanLotus ```use the same parameters```.\n<img src=\"__GHOST_URL__/content/images/2021/05/rotatecmp.png\" width=\"860px\" />\n## Similarity 4: Same instruction code\nBoth RotaJakiro and OceanLotus  use DWORD type instruction codes to specify the function of the message, and share several semantically identical instruction codes, some of which are featured as shown in the following table.\n| Cmd       | Function                                          |\n| --------- | ------------------------------------------------- |\n| 0x18320e0 | Upload device Info                                |\n| 0x2170272 | Register                                        |\n| 0x1B25503 | execute function from a plugin(a aynamic library) |\n| 0x1532e65 | execute function from a plugin(a aynamic library) |\n| 0x25D5082 | execute function from a plugin(a aynamic library) |\nThis similarity obviously cannot be explained by coincidence, **it is an extremely strong evidence of their code homology**.\n## Summary\nAlthough the RotaJakiro and the Mac version of the OceanLotus are implemented in different languages, their similarity in function and message format design, and their similarity in specific implementation, can no longer be explained by coincidence. **It is highly likely that RotaJakiro is a Linux version of the OceanLotus.**"}]],"markups":[],"sections":[[10,0],[1,"p",[]]],"ghostVersion":"3.0"}