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
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.
It is easy to see the commonalities between them.
- Both accept 3 parameters.
- 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.
|0x18320e0||Upload device Info|
|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.
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.