Library
My library

+ Add to library

Contact us
24/7 Tech support | Rules regarding submitting

Send a message

Your tickets

Profile

Back to the news list

Yet another [almost] non-removable trojan for Android

January 22, 2020

At the end of 2019, system-monitoring routines on some of our customers' smart phones detected changes in the file /system/lib/libc.so. This file is one of the key Linux libraries that facilitates basic system calls and routines. A closer examination yielded new malicious samples belonging to the Android.Xiny trojan family, which has been known to Doctor Web since 2015. To our knowledge, Android.Xiny programs were the first to make files read-only and, by doing so, make it harder to remove them from infected handsets. It looked pretty amusing: the application apk-file was assigned the read-only attribute; an attempt to remove the application was seemingly successful. But although the app data would indeed be deleted, the apk-file would remain intact. Consequently, the application would reappear after a reboot. We talked at length about this kind of trojan in 2016. To neutralise these threats, we enabled Dr.Web to reset file attributes. However, this feature could only be used if users granted root privileges to the anti-virus.

In this review, we will discuss another self-defence technique employed by newer versions of Android.Xiny malware.

Android 5.1? In 2020?

#drweb

The trojan we are examining in this article runs under Android 5.1 and below. It may seem strange that a malware program targeting these 'ancient' Android versions remains active (Android 5.1 was released in 2015). But, despite their age, the old versions are still in use. According to Google, as of May 7, 2019, 25.2% of active devices were running Android 5.1 and below. Our customer statistics showed a somewhat larger figure, about 26%. This means that a quarter of all Android-powered devices are potential targets. These devices are affected by vulnerabilities that will never be patched, so it is little wonder that virus makers are still interested in them. By exploiting the said vulnerabilities, attackers can acquire root permissions and enjoy free rein in a system, with the ability to do whatever they please. That said, more often than not, they use all that power to simply install more apps.

Trojan payload overview

Installing applications without user permission has always been Android.Xiny's principal function (even for its earliest versions). Thus, attackers can profit from pay-per-install referral programmes. As far as we can tell, these programmes generate a large portion of the income taken in by Android.Xiny’s makers. If some of the family species are launched on a target device, tons of harmless but completely useless applications will be installed and started on the handheld in just a minute, which will effectively render the device non-operational. Furthermore, the trojans can just as well install malware—everything depends on the instructions they receive from a command and control server.

Protection from removal is the most interesting distinguishing feature of new versions in the trojan family. The defence is maintained by two software components. Let's discuss them in more detail.

Installer

  • sha1: f9f87a2d2f4d91cd450aa9734e09534929170c6c
  • Detected as: Android.Xiny.5261

This trojan component is launched after root permissions have been acquired. To be launched automatically, it replaces the system files /system/bin/debuggerd and /system/bin/ddexe. The original files are saved by appending "_server" to their respective filenames. Furthermore, several other executable files that have been specified in the command string are copied into the system area. The trojan can also update the components it has installed into the system directories. To do so, the malware must be launched with certain command-line arguments and the location of the new file versions must be specified.

Android.Xiny.5261 contains an impressive list of the files it is meant to delete. The list includes paths to its older versions as well as to the files of its trojan rivals that also get installed into system directories. Those rivals include Triada, for example.

#drweb

In addition, Android.Xiny.5261 removes some preinstalled apps, possibly to free up some storage space. And, finally, it removes applications that are commonly used to administer root privileges (such as SuerSU and KingRoot). By doing so, it makes sure that users are unable to gain root access and remove the trojan components from system directories.

Modified system library libc.so

  • sha1: 171dba383d562bec235156f101879223bf7b32c7
  • Detected as: Android.Xiny.5260

This file interested us more than the others. Actually, our research started with an examination of this very file. If it’s opened in hiew, one may notice some executable code near the end of the .data section, which is quite suspicious.

#drweb

#drweb

Then we open the file in IDA to determine what kind of code we are dealing with.

It turns out that this file has the following routines modified: mount, execve, execv, execvp, execle, execl, execlp.

Here is the code of the altered version of mount:


int __fastcall mount(const char *source, const char *target, const char *filesystemtype,
unsigned int mountflags, const void *data) { unsigned __int8 systemPath[19]; // [sp+18h] [bp-1Ch] bool receivedMagicFlags; // [sp+2Bh] [bp-9h] int v13; // [sp+2Ch] [bp-8h] v13 = MAGIC_MOUNTFLAGS; // 0x7A3DC594 receivedMagicFlags = mountflags == MAGIC_MOUNTFLAGS; if ( mountflags == MAGIC_MOUNTFLAGS ) mountflags = 0x20; // MS_REMOUNT if ( receivedMagicFlags ) return call_real_mount(source, target, filesystemtype, mountflags, data); if ( mountflags & 1 ) // MS_RDONLY return call_real_mount(source, target, filesystemtype, mountflags, data); if ( getuid_() ) // not root return call_real_mount(source, target, filesystemtype, mountflags, data); memCopy(systemPath, (unsigned __int8 *)off_73210 + 471424, 8);// /system decrypt(systemPath, 8); if ( memCompare((unsigned __int8 *)target, systemPath, 8) || !isBootCompete() ) return call_real_mount(source, target, filesystemtype, mountflags, data); *(_DWORD *)errno_() = 13; return -1; }

First, the routine checks mountflags for the 'magic' value 0x7A3DC594. If the value has been passed to the routine, control is transferred to the original mount command. Then the code checks whether the OS boot-up process has completed and looks for attempts to remount the /system directory with read/write permissions. If the first condition is met, the real mount routine is not executed and an error is returned instead. In this way, the altered mount routine prevents other processes from mounting the system directory. Only the trojan can do that by passing that 'magic' value to the routine.

Here is the altered execve code (other exec* routines are modified in a similar fashion):


int __fastcall execve(const char *filename, char *const argv[], char *const envp[])
{
  int v3; // r3
  if ( targetInDataOrSdcard(filename) >= 0 )    // returns -1 if true
  {
    sub_7383C();
    v3 = call_real_execve(filename, argv, envp);
  }
  else
  {
    *(_DWORD *)errno_() = 13;
    v3 = -1;
  }
  return v3;
}

int __fastcall targetInDataOrSdcard(const char *path)
{
  char buf[516]; // [sp+8h] [bp-204h]
  if ( isDataOrSdcard(path) )
    return -1;
  if ( *path == '.' && getcwd_(buf, 0x200u) && isDataOrSdcard(buf) )
    return -1;
  return 0;
}

First, the code determines whether the path to the file being launched starts with “/data/" and whether the path string contains "/sdcard". If either of the conditions is met, the file won't be started. Note that /data/data/ directories store application files. So, no executable file can be launched from the directories where applications are allowed to create files.

These changes in libc.so are meant to disrupt the operation of apps that can be used to get root privileges. Because of the changes in the exec* routines, an application of this kind won't be able to run exploits to elevate its permissions—the exploits are usually downloaded from the Internet as executable files into the respective application's directory and then launched. If the program does get elevated privileges, the altered mount routine won't allow it to mount the system directory with write permissions and thus prevents the program from making any changes in the directory.

All in all, the trojan uses a two-tier defence: its installer removes applications that can grant root access to a user, whilst the altered library file libc.so prevents users from installing the programs again. Moreover, this mechanism keeps the trojans protected from their 'rivals' (other trojans that can elevate their privileges and copy their files into the system directory) because the competitors gain root access in the exact same way legitimate apps do.

How can these trojans be neutralised?

To get rid of Android.Xiny.5260, one can reflash the device if the corresponding firmware is available. But is there another way to delete the malware? It is difficult but not entirely impossible. There are several ways to accomplish this. To gain root access, one can resort to exploits that are implemented as library files. Unlike executable code, library code won't be blocked by the trojan. Another option is to use the trojan component that grants root permissions to its other components. The instruction is transmitted using this socket path: /dev/socket/hs_linux_work201908091350 (a different path may be used by other trojan versions). To circumvent the altered mount routine, one can use that very 'magic' mountflags value or invoke the required system call directly.

If your device has been infected by a trojan of this kind, we recommend that you reflash your device with official firmware. However, don't forget that reflashing a device deletes all user files and apps, so create backups before you proceed.

Tell us what you think

To ask Doctor Web’s site administration about a news item, enter @admin at the beginning of your comment. If your question is for the author of one of the comments, put @ before their names.


Other comments