Featured App installs itself

Published on February 19th, 2023 📆 | 3609 Views ⚑

0

Android.HeHe: Malware Now Disconnects Phone Calls


iSpeech.org

FireEye Labs has recently discovered six variants of a new Android
threat that steals text messages and intercepts phone calls. We named
this sample set “Android.HeHe” after the name of the activity that is
used consistently across all samples.

Here is a list of known bot variants:

MD5 VirusTotal Detection Ratio

1caa31272daabb43180e079bca5e23c1
1caa31272daabb43180e079bca5e23c1

2/48
2/48

8265041aca378d37006799975fa471d9
8265041aca378d37006799975fa471d9

1/47
1/47

2af4de1df7587fa0035dcefededaedae
2af4de1df7587fa0035dcefededaedae

2/45
2/45

2b41fbfb5087f521be193d8c1f5efb4c
2b41fbfb5087f521be193d8c1f5efb4c

2/46
2/46

aa0ed04426562df25916ff70258daf6c
aa0ed04426562df25916ff70258daf6c

1/46
1/46

9507f93d9a64d718682c0871bf354e6f
9507f93d9a64d718682c0871bf354e6f

1/47
1/47

Summary

The app disguises itself as “android security” (Figure 1),
attempting to provide the users what is advertised as an OS Update. It
contacts the command-and-control (CnC) server to register itself then
goes on to monitor incoming SMS messages. The CnC is expected to
respond with a list of phone numbers that are of interest to the
malware author. If one of these numbers sends an SMS or makes a call
to an infected device, the malware intercepts the message or call,
suppresses device notifications from the device, and removes any trace
of the message or call from device logs. Any SMS messages from one of
these numbers are logged into an internal database and sent to the CnC
server. Any phone calls from these numbers are silenced and rejected.

Figure 1

Analysis

This app starts the main HeHe activity at startup. The constructor
of the HeHeActivity registers a handler using the
android.os.Handle
, which acts as a thread waiting for an object of
type android.os.Message to perform different actions, which are
outlined below.

Because the HeHeActivity implements the standard
DailogInterfaceOnClickListener, the start of the app causes the
showAlterDailog message to be displayed (Figure 2).

Fake OS Update in progress

The app then sends an intent to start three services in the
background. These services are explained below.

Sandbox-evasion tactic

This app checks for the presence of an emulator by calling the
isEmulator function, which does the following:

  1. It checks the value of the MODEL of the device
    (emulators with the Google ADT bundle have the string “sdk” as a
    part of the MODEL variable).
  2. It also checks to see
    if the IMSI code is “null” — emulators do not have an IMSI code
    associated with them.

Here is the isEmulator code:

String v0 = TelephonyUtils.getImsi(((Context)this));
if(v0 ==
null) {

return;
}
public static boolean isEmulator()
{
boolean v0;
if((Build.MODEL.equalsIgnoreCase("sdk")) ||
(Build.MODEL.equalsIgnoreCase("google_sdk"))) {
v0 =
true;
}
else {
v0 = false;
}
return
v0;
}

The code checks whether the the app is being run in the Android QEMU emulator. It also checks whether the value of IMSI is equal to null


RegisterService

This service runs in the background. Once started the app calls the
setComponentEnabledSetting method as follows:

this.getPackageManager().setComponentEnabledSetting(new ComponentName(((Context)this), HeheActivity.class), 2, 1);

This removes the app from the main menu of the phone leading the
user to believe that the app is no longer installed on the phone. It
then goes on to check the network status of the phone as shown below

public void checkNetwork() { 
if(!this.isNetworkAvailable()) {
this.setMobileDataEnabled();
}
}

After the service has been created. The onStart method is called, which checks the message provided as a part of the intent. The message types are START and LOGIN



START

If the message in the intent is START, The app calls the
sendReigsterRequest() function. The sendRegisterRequest
function first checks for the presence of an emulator as explained in
the "Sandbox-evasion tactic" section

It then collects the IMSI IMEI, phone number, SMS address and
channel ID. It packs all this information into a JSON object. Once the
JSON object is created. It is converted to a string, which is sent to
the CnC server. The CnC communication is explained below.


LOGIN

If the message in the intent is LOGIN, the app calls the
sendLoginRequest method, which in turn collects the following:

  • Version number of the app (hard-coded as
    "1.0.0")
  • The model of the phone
  • The
    version of the operating system
  • The type of network
    associated with the device (GSM/CDMA)

This information is also packed into a JSON object, converted into a
string, and sent to the CnC server.


RegisterBroadcastReceiver service

This service is invoked at the start of the app as the
RegisterService. It in turn registers the
IncomeCallAndSmsReceiver(), which is set to respond to these
three intents:

  • android.provider.Telephony.SMS_RECEIVED, which notifies once
    a SMS has been received on the device
  • android.intent.action.PHONE_STATE, which notifies once the
    cellular state of the device has changed. Examples include
    RINGING and OFF_HOOK.
  • android.intent.action.SCREEN_ON, which notifies once the
    screen has been turned on or turned off.

Additionally, it also sets observers over Android content URIs as follows:

  • The SmsObserver is set to observe the content://sms,
    which enables it to access all SMS messages that are present on the
    device.
  • The CallObserver is set to observe the
    content://call_log/calls, which allows it to access the call log of
    all incoming, outgoing and missed calls on the device.

 ConnectionService

The main HeHe activity mentioned at the start issues the
ACTION_START
intent to the ConnectionService class as follows:

Intent v2 = new Intent(((Context)this), ConnectionService.class);

v2.setAction(ConnectionService.ACTION_START);

v2.setFlags(268435456); this.startService(v2); LogUtils.debug("heheActivity", "start connectionService service"); The app then starts a timer task that is scheduled to be invoked every 5000 seconds. This timed task does the following:
  • Creates an object instance of the android.os.Message
    class
  • Sets the value of "what" in the
    Message object to 1
  • The handler of this message that
    was initiated in the constructor then gets called which, in turn
    calls the showFinishBar function that displays the message
    “현재 OS에서 최신 소프트웨어버전을 사용하고있습니다,” which translates to “The current OS
    you are using the latest version of the software.”

Receivers


IncomeCallAndSmsReceiver





The RegisterBroadcastReceiver registers this receiver once
the app gets started. When an SMS is received on the device. The
IncomeCallAndSmsReceiver gets the intent. Because this receiver
listens for one of three intents, any intents received by this
receiver are checked for their type.

If the received intent is of type
android.provider.telephony.SMS_RECEIVED, the app extracts the
contents of the SMS and the phone number of the sender. If the first
three characters of the phone number matches the first three
characters from phone numbers in a table named tbl_intercept_info,
then the SMS intent is aborted and the SMS is deleted from the devices
SMS inbox so that the user never sees it. After the SMS notification
is suppressed, the app bundles the SMS as follows:

{
"content":"TESTING", 
"createTime":"2014-01-10 16:21:36",
"id":null,"messageFrom":"1234567890",
"token":null
}

From there, it sends the to the CnC server (http://108.62.240.69:9008/reportMessage)

It also records the SMS in the tbl_message_info table in its
internal database.

If the received intent is of type
android.intent.action.PHONE_STATE
, the app checks the
tbl_intercept_info table in the local database. If the number of the
caller appears in this table, then the ringer mode of the phone is set
to silent to suppress the notification of the incoming call and the
phone call is disconnected. Its corresponding entry from the call logs
is also removed, removing all traces of the phone call from the device.

No actions have been defined for the
android.app.action.SCREEN_ON intent, even though the
IncomeCallAndSmsReceiver receiver is the recipient.

CnC

This app uses two hard-coded IP address to locate its CnC servers:
122.10.92.117 and 58.64.183.12. The app performs all
communications through HTTP POST requests. The contents of the
HTTP POST are encrypted using AES with a 128-bit key that is hardcoded
into the app. The app sends its lastVersion value —to
122.10.92.117, to address is where is used to check for , in which the
app sends its version of the app. The address 58.64.183.12 is used to
report incoming SMS messages

Because the IP address is no longer reachable, responses from the
server could not be analyzed. What is clear is that the server sends a
JSON object in response, which contains a "token" field.

Although the CnC server is currently unavailable, we can infer how
the app works by examining the how it processes the received responses.

The app consists of different data structures that are converted
into their equivalent JSON representations when they are sent to the
CnC. Also, All JSON object responses are converted into their
equivalent internal data structures. We have also observed the
mechanism used to populate the internal database which includes tables
(tbl_intercept_info) which contain the phone numbers to be blocked.

The app uses hxxp://122.10.92.117:9008 and hxxp://58.64.183.12:9008
to send information to the CnC server.

The mapping of URLs to their internal class data structures is as follows:

GetLastVersionRequest /getLastVersion
RegisterRequest /register
LoginRequest /login
ReportRequest /report
GetTaskRequest /getTask
ReportMessage
Request
/reportMessage

The meaning and structures of these are explained in the following sections.


GetLastVersionRequest

This request is sent when the app is first installed on the device.
The bot sends the version code of the device (currently set to 1.0.0)
to the CnC. The CnC response shall contain the URL to an update if
available. The availability of an update is signified through an
‘update’ field in the response

Request to CnC to check for version


RegisterRequest

This request is sent when the app sends an intent with a “LOGIN”
option to the RegisterService as explained  above. The request
contains the IMSI, IMEI, Phone number, SMS address (Phone number),
Channel ID, a token and the IP address being used by the app as its
CnC. This causes the infected device to be registered with the CnC.


LoginRequest

This request is sent to further authenticate the device to the CnC,
It contains the token previously received, the version of the Bot, the
model of the phone, the version of the OS, the type of network and the
other active network parameters such as signal strength. In response,
It only gets a result value.


ReportRequest

The report request sends the information present in tbl_report_info
to the CnC. This table contains information about other requests that
were sent but failed.


GetTaskRequest

This requests asks for tasks from the CnC server. The response
contains a retry interval and a sendSmsActionNotify value. It is sent
when the response to the LoginRequest is 401 instead of 200.


ReportMessageRequest

This request to the CnC sends the contents of the SMS messages that
are received on the device. It consists of the contents of the SMS
message, the time of the message and the sender of the SMS. This has
been observed in the logcat output as follows:

logging-mini

Conclusion

Android malware variants are mushrooming. Threats such as
Android.HeHe and Android.MisoSMS
reveal attackers' growing interest in monitoring SMS messages and
phone call logs. They also serve as a stark reminder of just how
dangerous apps from non-trusted marketplaces can be.

Source link

Tagged with:



Comments are closed.