├── LICENSE ├── README.md ├── pom.xml ├── src └── main │ └── java │ ├── anubis │ ├── bot │ │ ├── AnubisBot.java │ │ ├── AnubisConfig.java │ │ └── AnubisEncryptionHandler.java │ └── commands │ │ ├── AutoPush.java │ │ ├── CallForwarder.java │ │ ├── CheckPermissions.java │ │ ├── Cryptolocker.java │ │ ├── DecryptFileSystem.java │ │ ├── GetAllInstalledApplications.java │ │ ├── GetIp.java │ │ ├── GetKeyloggerData.java │ │ ├── GetPhoneBookNumbers.java │ │ ├── GetPlayProtectApk.java │ │ ├── GetRansomNote.java │ │ ├── GetSavedSmsMessages.java │ │ ├── KillBot.java │ │ ├── OpenActivity.java │ │ ├── OpenUrlInBrowser.java │ │ ├── RecordSound.java │ │ ├── ReplaceUrl.java │ │ ├── RequestGpsAccessPermission.java │ │ ├── RequestUsageAccessPermission.java │ │ ├── SendGoSms.java │ │ ├── SendPushNotification.java │ │ ├── SendSmsMessagesViaPhoneContacts.java │ │ ├── ShowMessageBox.java │ │ ├── Socks5.java │ │ ├── SpamSms.java │ │ ├── StartAccessibilityService.java │ │ ├── StartApplication.java │ │ ├── StartInj.java │ │ ├── StartPermissions.java │ │ ├── StartRat.java │ │ ├── StartUssd.java │ │ └── StopSocks5.java │ ├── bot │ ├── Bot.java │ ├── Config.java │ ├── Families.java │ ├── IBot.java │ ├── IConfig.java │ ├── LocalFileSystemManager.java │ ├── cryptography │ │ ├── GenericCryptographyHandler.java │ │ └── Rc4.java │ └── network │ │ └── Connector.java │ ├── cerberus │ ├── bot │ │ ├── CerberusBot.java │ │ ├── CerberusConfig.java │ │ └── CerberusEncryptionHandler.java │ └── commands │ │ ├── DeleteApplication.java │ │ ├── ForwardCall.java │ │ ├── GetContacts.java │ │ ├── GetInstalledApps.java │ │ ├── GetSms.java │ │ ├── KillMe.java │ │ ├── OpenUrl.java │ │ ├── SendNotification.java │ │ ├── SendSms.java │ │ ├── SendSmsAll.java │ │ ├── ServiceWorkingWhile.java │ │ ├── StartAdmin.java │ │ ├── StartApplication.java │ │ ├── StartAuthenticator2.java │ │ ├── StartInject.java │ │ ├── StartUssd.java │ │ ├── StartViewInject.java │ │ ├── UpdateInjectAndListApps.java │ │ ├── UpdateModule.java │ │ └── UpdateSettingsAndCommands.java │ ├── config │ ├── ConfigCreator.java │ ├── ConfigHelperCli.java │ ├── ConfigHelperManual.java │ └── ConfigLoader.java │ ├── device │ ├── Contact.java │ ├── Phone.java │ ├── SharedPreferences.java │ ├── SmsManager.java │ ├── SmsMessage.java │ └── enums │ │ ├── Permissions.java │ │ └── VersionCodes.java │ ├── emulator │ ├── Emulator.java │ └── OptionsGenerator.java │ └── scheduler │ └── BotScheduler.java └── target ├── apidocs.zip └── m3-1.0-stable-jar-with-dependencies.jar /README.md: -------------------------------------------------------------------------------- 1 | # m3 2 | A simple and scalable Android bot emulation framework. A detailed explanation can be found here. This project was first published at Black Hat Europe 2021's Arsenal. 3 | 4 | Aside from the documentation in the code (both in-line and as JavaDoc), one can learn more about extending the framework here. The two currently implemented families, Anubis and Cerberus, are explained in detail here. Questions can always be asked via Twitter @Libranalysis (both publicly or via a DM), or an issue can be opened in this repository. 5 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | m3 5 | m3 6 | 1.0-stable 7 | jar 8 | 9 | UTF-8 10 | 1.8 11 | 1.8 12 | 13 | 14 | 15 | central 16 | Central Repository 17 | https://repo.maven.apache.org/maven2 18 | default 19 | 20 | false 21 | 22 | 23 | never 24 | 25 | 26 | 27 | 28 | 29 | central 30 | Central Repository 31 | https://repo.maven.apache.org/maven2 32 | default 33 | 34 | false 35 | 36 | 37 | 38 | 39 | 40 | 41 | maven-assembly-plugin 42 | 43 | 44 | 45 | emulator.Emulator 46 | 47 | 48 | 49 | jar-with-dependencies 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | 3.2.1 56 | maven-source-plugin 57 | 58 | 59 | attach-sources 60 | 61 | jar 62 | 63 | 64 | 65 | 66 | 67 | org.apache.maven.plugins 68 | 3.2.0 69 | maven-javadoc-plugin 70 | 71 | 72 | attach-javadocs 73 | 74 | jar 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | org.json 85 | json 86 | 20200518 87 | 88 | 89 | 90 | com.google.code.gson 91 | gson 92 | 2.8.6 93 | 94 | 95 | 96 | commons-cli 97 | commons-cli 98 | 1.4 99 | 100 | 101 | 102 | commons-codec 103 | commons-codec 104 | 1.15 105 | 106 | 107 | m3 108 | -------------------------------------------------------------------------------- /src/main/java/anubis/bot/AnubisConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.bot; 18 | 19 | import bot.Config; 20 | import bot.IConfig; 21 | import device.Contact; 22 | import device.SharedPreferences; 23 | import device.SmsManager; 24 | import java.time.LocalDateTime; 25 | import java.util.List; 26 | import java.util.Set; 27 | 28 | /** 29 | * The configuration file for Anubis, which implements the IConfig interface and 30 | * the abstract Config class. The abstract class contains all generic fields, 31 | * meaning only additional values are required to be stored in this class. 32 | * 33 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 34 | */ 35 | public class AnubisConfig extends Config implements IConfig { 36 | 37 | /** 38 | * The RC-4 key to encrypt and decrypt data 39 | */ 40 | private String rc4Key; 41 | 42 | /** 43 | * The folder where the PHP files reside on the Anubis C2 folder, excluding 44 | * the domain, and without any leading or trailing slashes. In this example 45 | * URL: "127.0.0.1/abc/a11.php", the folder name is "abc" 46 | */ 47 | private String serverFolder; 48 | 49 | /** 50 | * Creates an Anubis bot based on the given data 51 | * 52 | * @param nextPollMoment the next moment in time to poll 53 | * @param botName the bot's internal name, which is only used locally 54 | * @param botFamily the bot's family 55 | * @param tag the bot's tag 56 | * @param localFileSystem the full path to the local file system folder 57 | * @param imei a fake IMEI number 58 | * @param number a fake phone number 59 | * @param networkOperatorName a fake network operator name 60 | * @param locale an ISO-3166-1 alpha-2 country code 61 | * @param version the phone's fake version, as defined in 62 | * Build.VERSION.RELEASE 63 | * @param model the phone's fake model, as defined in Build.MODEL 64 | * @param product the phone's fake product, as defined in Build.PRODUCT 65 | * @param smsManager the phone's SMS manager 66 | * @param contacts fake contacts 67 | * @param sharedPreferences shared preferences for the phone 68 | * @param permissions the bot's permissions on the phone 69 | * @param installedApplications a list of installed applications on the 70 | * phone 71 | * @param server the C2 server WITHOUT any trailing slashes 72 | * @param oldServers a list of old C2 servers 73 | * @param registered a boolean that defines if the bot is registered 74 | * @param userAgent the user-agent to use when contacting the C2 75 | * @param interval the interval in seconds between the polling moments 76 | * @param rooted a boolean that defines if the phone is rooted 77 | * @param defaultSmsManager the default SMS manager object 78 | * @param deviceAdmin a boolean that defines if the bot has admin privileges 79 | * on the device 80 | * @param locked a boolean that defines if the phone's screen is locked 81 | * @param batteryPercentage the battery percentage of the phone 82 | * @param active a boolean that defines if this bot is active 83 | * @param proxyAddress the address of the proxy server (provide null if no 84 | * proxy should be used) 85 | * @param proxyPort the port of the proxy server (provide null if no proxy 86 | * should be used) 87 | * @param rc4Key the RC-4 key that is used to encrypt and decrypt data 88 | * @param serverFolder the folder that contains the Anubis PHP files, 89 | * without trailing nor leading slashes 90 | */ 91 | public AnubisConfig(LocalDateTime nextPollMoment, String botName, String botFamily, String tag, String localFileSystem, String imei, String number, String networkOperatorName, String locale, String version, String model, String product, SmsManager smsManager, List contacts, SharedPreferences sharedPreferences, Set permissions, Set installedApplications, String server, List oldServers, boolean registered, String userAgent, int interval, boolean rooted, boolean defaultSmsManager, boolean deviceAdmin, boolean locked, int batteryPercentage, boolean active, String proxyAddress, Integer proxyPort, String rc4Key, String serverFolder) { 92 | super(nextPollMoment, botName, botFamily, tag, localFileSystem, imei, number, networkOperatorName, locale, version, model, product, smsManager, contacts, sharedPreferences, permissions, installedApplications, server, oldServers, registered, userAgent, interval, rooted, defaultSmsManager, deviceAdmin, locked, batteryPercentage, active, proxyAddress, proxyPort); 93 | this.rc4Key = rc4Key; 94 | this.serverFolder = serverFolder; 95 | } 96 | 97 | /** 98 | * Gets the RC-4 key to encrypt and decrypt data 99 | * 100 | * @return the RC-4 key 101 | */ 102 | public String getRc4Key() { 103 | return rc4Key; 104 | } 105 | 106 | /** 107 | * The folder where the PHP files reside on the Anubis C2 folder, excluding 108 | * the domain, and without any leading or trailing slashes. In this example 109 | * URL: "127.0.0.1/abc/a11.php", the folder name is "abc" 110 | * 111 | * @return the server folder 112 | */ 113 | public String getServerFolder() { 114 | return serverFolder; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/anubis/bot/AnubisEncryptionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.bot; 18 | 19 | import bot.cryptography.GenericCryptographyHandler; 20 | import bot.cryptography.Rc4; 21 | import java.nio.charset.Charset; 22 | 23 | /** 24 | * This class provides helper functions to more easily encrypt and decrypt data 25 | * in the way that the Anubis bot requires 26 | * 27 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 28 | */ 29 | public class AnubisEncryptionHandler extends GenericCryptographyHandler { 30 | 31 | /** 32 | * The RC-4 object to handle RC-4 operations 33 | */ 34 | private Rc4 rc4; 35 | 36 | /** 37 | * Creates an instance of this helper class, which contains the routines to 38 | * easily encrypt and decrypt data in the way that the Anubis bot requires 39 | * 40 | * @param rc4Key the RC-4 key 41 | */ 42 | public AnubisEncryptionHandler(String rc4Key) { 43 | this.rc4 = new Rc4(rc4Key.getBytes()); 44 | } 45 | 46 | /** 47 | * Encrypts data in the way that Anubis requires 48 | * 49 | * @param input the input to encrypt 50 | * @return the encrypted output 51 | */ 52 | public String encrypt(String input) { 53 | byte[] tempByteArray = rc4.encrypt(input.getBytes()); 54 | tempByteArray = bytesToHexString(tempByteArray).getBytes(); 55 | return getBase64().encodeToString(tempByteArray); 56 | } 57 | 58 | /** 59 | * Removes the default tags from the given string 60 | * 61 | * @param text the string to remove the tags from 62 | * @return the tagless input 63 | */ 64 | public String untag(String text) { 65 | String tagPrefix = ""; 66 | String tagPostfix = ""; 67 | return untag(text, tagPrefix, tagPostfix); 68 | } 69 | 70 | /** 71 | * Removes the given tags from the given text 72 | * 73 | * @param text the text to remove the tags from 74 | * @param tagPrefix the prefix to remove 75 | * @param tagPostfix the postfix to remove 76 | * @return the tagless input 77 | */ 78 | public String untag(String text, String tagPrefix, String tagPostfix) { 79 | try { 80 | int start = text.indexOf(tagPrefix) + tagPrefix.length(); 81 | int end = text.indexOf(tagPostfix); 82 | text = text.substring(start, end); 83 | return text; 84 | } catch (Exception e) { 85 | return ""; 86 | } 87 | } 88 | 89 | /** 90 | * Decrypts data in the way that Anubis requires 91 | * 92 | * @param input the input to decrypt 93 | * @return the decrypt output 94 | */ 95 | public String decrypt(String input) { 96 | String response = new String(getBase64().decode(input), Charset.forName("UTF-8")); 97 | byte[] byteArray = hexStringToByteArray(response); 98 | byte[] decrypted = rc4.decrypt(byteArray); 99 | String output = new String(decrypted); 100 | return output; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/AutoPush.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * This class handles the command to execute a push notification on the bot 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class AutoPush { 27 | 28 | /** 29 | * This class handles the command to execute a push notification on the bot 30 | * 31 | * @param bot the bot 32 | * @param command the command's parameter 33 | */ 34 | public AutoPush(AnubisBot bot, String command) { 35 | String appName = bot.getEncryptionHandler().untag(command, "|AppName=", "|EndAppName"); 36 | String title; 37 | String text; 38 | String locale = bot.getPhone().getLocale().toUpperCase(); 39 | if (locale.contains("RU")) { 40 | title = "Срочное сообщение!"; 41 | text = "Подтвердите свой аккаунт"; 42 | } else if (locale.contains("US")) { 43 | title = "Urgent message!"; 44 | text = "Confirm your account"; 45 | } else if (locale.contains("TR")) { 46 | title = "Acil mesaj!"; 47 | text = "Hesabını onayla"; 48 | } else if (locale.contains("DE")) { 49 | title = "Dringende Nachricht!"; 50 | text = "Bestätigen Sie ihr Konto"; 51 | } else if (locale.contains("IT")) { 52 | title = "Messaggio urgente!"; 53 | text = "Conferma il tuo account"; 54 | } else if (locale.contains("FR")) { 55 | title = "Message urgent!"; 56 | text = "Confirmez votre compte"; 57 | } else if (locale.contains("UA")) { 58 | title = "Термінове повідомлення!"; 59 | text = "Підтвердьте свій рахунок"; 60 | } else { 61 | title = "Urgent message!"; 62 | text = "Confirm your account"; 63 | } 64 | String log = "Received the command to automatically show a push notification:\n" 65 | + "\tTargeted application: " + appName + "\n" 66 | + "\tNotification title: " + title + "\n" 67 | + "\tNotification text: " + text; 68 | bot.addLog(log); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/CallForwarder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * This class handles the commands to start and stop forwarding calls 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class CallForwarder { 27 | 28 | /** 29 | * The number to forward calls to, as received from the C2 server 30 | */ 31 | private String number; 32 | 33 | /** 34 | * This constructor is used to start the forwarding of calls. The number to 35 | * forward the calls to is also stored in the phone's shared preferences, 36 | * under the "forwardingNumber" key 37 | * 38 | * @param bot the bot 39 | * @param command the command to handle 40 | */ 41 | public CallForwarder(AnubisBot bot, String command) { 42 | number = bot.getEncryptionHandler().untag(command, "startforward=", "|endforward"); 43 | bot.getPhone().getSharedPreferences().write("forwardingNumber", number); 44 | String log = "Started forwarding incoming calls to " + number; 45 | bot.addLog(log); 46 | } 47 | 48 | /** 49 | * This constructor is used to stop the forwarding of the calls 50 | * 51 | * @param bot the bot 52 | */ 53 | public CallForwarder(AnubisBot bot) { 54 | if (bot.getPhone().getSharedPreferences().read("forwardingNumber") == null || bot.getPhone().getSharedPreferences().read("forwardingNumber").isEmpty()) { 55 | number = "[no-defined-number]"; 56 | } 57 | String log = "Stopped forwarding incoming calls to " + number; 58 | bot.addLog(log); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/CheckPermissions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | import device.enums.Permissions; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | /** 25 | * This class handles the check permission command 26 | * 27 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 28 | */ 29 | public class CheckPermissions { 30 | 31 | /** 32 | * Checks the permissions of the bot, and reports back to the C2 with the 33 | * permission status of the few listed permissions within this function 34 | * 35 | * @param bot the bot 36 | * @throws Exception if the HTTP request fails 37 | */ 38 | public CheckPermissions(AnubisBot bot) throws Exception { 39 | //Permissions to check for, per the bot's source 40 | List localPermissions = new ArrayList<>(); 41 | localPermissions.add(Permissions.SEND_SMS); 42 | localPermissions.add(Permissions.WRITE_EXTERNAL_STORAGE); 43 | localPermissions.add(Permissions.READ_CONTACTS); 44 | localPermissions.add(Permissions.ACCESS_FINE_LOCATION); 45 | localPermissions.add(Permissions.CALL_PHONE); 46 | localPermissions.add(Permissions.RECORD_AUDIO); 47 | 48 | String permissionOutput = "All permissions:" + "\n"; 49 | 50 | for (String localPermission : localPermissions) { 51 | if (bot.getPhone().getPermissions().contains(localPermission)) { 52 | permissionOutput = permissionOutput + localPermission + ": OFF" + "\n"; 53 | } else { 54 | permissionOutput = permissionOutput + localPermission + ": ON" + "\n"; 55 | } 56 | } 57 | 58 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a6.php"; 59 | String parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|" + permissionOutput + "|"); 60 | 61 | bot.getConnector().post(url, parameter); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/Cryptolocker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * This class handles the cryptolocker command 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class Cryptolocker { 27 | 28 | /** 29 | * This class handles the cryptolocker command 30 | * 31 | * @param bot the bot 32 | * @param command the command 33 | */ 34 | public Cryptolocker(AnubisBot bot, String command) { 35 | String[] values = bot.getEncryptionHandler().untag(command, "|cryptokey=", "|endcrypt").split("/:/"); 36 | if (values.length == 3) { 37 | String key = values[0]; 38 | String amount = values[1]; 39 | String btc = values[2]; 40 | 41 | String log = "Received command to cryptolock the device:\n" 42 | + "\tKey: " + key + "\n" 43 | + "\tAmount: " + amount + "\n" 44 | + "\tBTC: " + btc; 45 | bot.addLog(log); 46 | 47 | //store lock_amount, lock_btc, status (equals crypt), and the key in the shared preferences 48 | bot.getPhone().getSharedPreferences().write("lock_amount", amount); 49 | bot.getPhone().getSharedPreferences().write("lock_btc", btc); 50 | bot.getPhone().getSharedPreferences().write("status", "crypt"); 51 | bot.getPhone().getSharedPreferences().write("key", key); 52 | 53 | log = "Changed the following shared preferences:\n" 54 | + "\t'lock_amount' : " + amount + "\n" 55 | + "\t'lock_btc' : " + btc + "\n" 56 | + "\t'status' : 'crypt'\n" 57 | + "\t'key' : " + key; 58 | bot.addLog(log); 59 | } else { 60 | bot.addLog("Failed to properly handle the cryptolocker command, as the incoming command was malformed"); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/DecryptFileSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * This class handles the decryption of the bot's file system (albeit that no 23 | * files were ever encrypted in this emulation) 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class DecryptFileSystem { 28 | 29 | /** 30 | * Handles the decryption command 31 | * 32 | * @param bot the bot 33 | * @param command the command 34 | */ 35 | public DecryptFileSystem(AnubisBot bot, String command) { 36 | String key = bot.getEncryptionHandler().untag(command, "|decryptokey=", "|enddecrypt"); 37 | 38 | String log = "Received the decrypt command with the following key: " + key; 39 | bot.addLog(log); 40 | 41 | bot.getPhone().getSharedPreferences().write("status", "decrypt"); 42 | bot.getPhone().getSharedPreferences().write("key", key); 43 | 44 | log = "Changed the following shared preferences:\n" 45 | + "\t'status': 'decrypt'\n" 46 | + "\t'key' : " + key; 47 | bot.addLog(log); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/GetAllInstalledApplications.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import bot.network.Connector; 20 | import anubis.bot.AnubisBot; 21 | import java.util.Set; 22 | 23 | /** 24 | * This class handles the command to obtain all installed applications on the 25 | * device 26 | * 27 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 28 | */ 29 | public class GetAllInstalledApplications { 30 | 31 | /** 32 | * Handles the command to upload all the package names of the installed 33 | * applications to the C2 34 | * 35 | * @param bot the bot 36 | * @throws Exception if the HTTP request fails 37 | */ 38 | public GetAllInstalledApplications(AnubisBot bot) throws Exception { 39 | String log = "Received command to provide all installed applications, which are:\n"; 40 | 41 | String result = "All Installed Applications:\n"; 42 | Set installedApplications = bot.getPhone().getInstalledApplications(); 43 | for (String application : installedApplications) { 44 | result = result + application + "\n"; 45 | log += "\t" + application + "\n"; 46 | } 47 | log = log.substring(0, log.length() - 1); 48 | bot.addLog(log); 49 | 50 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a6.php"; 51 | Connector connector = bot.getConnector(); 52 | String parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|" + result + "|"); 53 | connector.post(url, parameter); 54 | 55 | log = "Responded to the server with a list of all installed applications"; 56 | bot.addLog(log); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/GetIp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import bot.network.Connector; 20 | import anubis.bot.AnubisBot; 21 | 22 | /** 23 | * This class handles the command to get the IP from the bot. NOTE THAT THIS 24 | * WILL UPLOAD YOUR ACTUAL IP IF YOU ARE NOT USING A PROXY SERVER! 25 | * 26 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 27 | */ 28 | public class GetIp { 29 | 30 | /** 31 | * This class handles the command to get the IP from the bot. NOTE THAT THIS 32 | * WILL UPLOAD YOUR ACTUAL IP IF YOU ARE NOT USING A PROXY SERVER! 33 | * 34 | * @param bot the bot 35 | * @throws Exception if a HTTP request fails 36 | */ 37 | public GetIp(AnubisBot bot) throws Exception { 38 | String log = "Received command to send IP to the server"; 39 | bot.addLog(log); 40 | 41 | String result = bot.getConnector().post("http://en.utrace.de", ""); //No parameters for the request. 42 | 43 | Connector connector = bot.getConnector(); 44 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a6.php"; 45 | String ip = bot.getEncryptionHandler().untag(result, ">The IP address ", " is located in the"); 46 | String parameters = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|IP bots: " + ip + "\n" + "|"); 47 | connector.post(url, parameters); 48 | 49 | log = "Responded to the server with IP: " + ip; 50 | bot.addLog(log); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/GetKeyloggerData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import bot.network.Connector; 20 | import anubis.bot.AnubisBot; 21 | import java.io.IOException; 22 | 23 | /** 24 | * This class handles the upload of logged keystrokes to the C2 25 | * 26 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 27 | */ 28 | public class GetKeyloggerData { 29 | 30 | /** 31 | * This class handles the upload of logged keystrokes to the C2 32 | * 33 | * @param bot the bot 34 | * @throws Exception if the HTTP request fails 35 | */ 36 | public GetKeyloggerData(AnubisBot bot) throws Exception { 37 | String log = "Received command to retrieve all keylogger data"; 38 | bot.addLog(log); 39 | 40 | } 41 | 42 | /** 43 | * A function to upload the logs in the correct format. Currently, m3 does 44 | * not support the creation of fake keystroke logging. If one were to 45 | * implement it, the base to do so is given below. 46 | * 47 | * @param bot the bot 48 | * @throws IOException if there is an error whilst reading the log file 49 | * @throws Exception if the HTTP request fails 50 | */ 51 | private void uploadLogs(AnubisBot bot) throws IOException, Exception { 52 | String s = bot.getLocalFileSystemManager().readStringFromPath("keys.log"); 53 | s = s.replace("|^|", "\n"); 54 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a12.php"; 55 | Connector connector = bot.getConnector(); 56 | String parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "~~~~~~~~~~" + s); 57 | String response = connector.post(url, parameter); 58 | response = bot.getEncryptionHandler().untag(response); 59 | response = bot.getEncryptionHandler().decrypt(response); 60 | 61 | String log = ""; 62 | if (response.contains("clear")) { //the default response, or its empty if something goes wrong 63 | //Empty log file 64 | bot.getLocalFileSystemManager().overwriteFile(new byte[0], "keys.log"); 65 | log = "Log file received by the server and cleared locally"; 66 | } else { 67 | log = "The server did not respond properly, which might mean that the server is down"; 68 | } 69 | bot.addLog(log); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/GetPhoneBookNumbers.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import bot.network.Connector; 20 | import anubis.bot.AnubisBot; 21 | import device.Contact; 22 | import java.util.List; 23 | 24 | /** 25 | * This class handles the command to upload all contacts to the C2 26 | * 27 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 28 | */ 29 | public class GetPhoneBookNumbers { 30 | 31 | /** 32 | * This class handles the command to upload all contacts to the C2 33 | * 34 | * @param bot the bot 35 | * @throws Exception if a HTTP request fails 36 | */ 37 | public GetPhoneBookNumbers(AnubisBot bot) throws Exception { 38 | String log = "Received command to get all contacts"; 39 | bot.addLog(log); 40 | 41 | //Only enter this routine if getNumber == true in the shared preferences 42 | String result = "(" + bot.getPhone().getLocale() + ") Numbers from the phone book"; 43 | 44 | Connector connector = bot.getConnector(); 45 | 46 | List contacts = bot.getPhone().getContacts(); 47 | for (Contact contact : contacts) { 48 | String name = contact.getName(); 49 | String number = contact.getNumber(); 50 | 51 | if ((!number.contains("*")) && (!number.contains("#")) && (number.length() > 6) && (!result.contains(number))) { 52 | result = result + number + " " + name + "
" + '\n'; 53 | } 54 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a6.php"; 55 | String parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|" + result + "|"); 56 | String response = connector.post(url, parameter); 57 | 58 | //Sets the getNumber value to true in the shared preferences 59 | bot.getPhone().getSharedPreferences().write("getNumber", "true"); 60 | if (response.contains("||ok||")) { 61 | log = "Responded to the server with all contacts within the current configuration"; 62 | } else { 63 | log = "Server failed to respond properly to the uploaded contacts"; 64 | } 65 | bot.addLog(log); 66 | //Returns ||ok|| if received or empty if an error occurs 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/GetPlayProtectApk.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | import org.apache.commons.codec.binary.Base64; 21 | 22 | /** 23 | * Handles the download of the Play Protect module 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class GetPlayProtectApk { 28 | 29 | /** 30 | * Handles the download of the Play Protect module 31 | * 32 | * @param bot the bot 33 | * @throws Exception if a HTTP request fails 34 | */ 35 | public GetPlayProtectApk(AnubisBot bot) throws Exception { 36 | String fileName = "playProtect.apk"; 37 | 38 | //Instantly return if the play protect APK is already present on the local file system 39 | if (bot.getLocalFileSystemManager().exists(fileName)) { 40 | return; 41 | } 42 | 43 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a14.php"; 44 | String parameter = "p=1"; 45 | 46 | String log = "Attempting to download the Play Protect APK module"; 47 | bot.addLog(log); 48 | 49 | String response = bot.getConnector().post(url, parameter); 50 | String noTags = bot.getEncryptionHandler().untag(response); 51 | String decrypted = bot.getEncryptionHandler().decrypt(noTags); 52 | 53 | if (decrypted.length() > 1000) { 54 | byte[] apk = new Base64().decode(decrypted); 55 | String path = bot.getLocalFileSystemManager().writeFile(apk, fileName); 56 | log = "Downloaded the Play Protect APK module (with a size of " + apk.length + " bytes)\n" 57 | + "\tThe file is located at \"" + path + "\""; 58 | } else { 59 | log = "Download failed as the length is less than 1000 bytes, per the bot's original code"; 60 | } 61 | bot.addLog(log); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/GetRansomNote.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * Gets the ransom note from the server 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class GetRansomNote { 27 | 28 | /** 29 | * Gets the ransom note from the server 30 | * 31 | * @param bot the bot 32 | * @throws Exception if a HTTP request fails 33 | */ 34 | public GetRansomNote(AnubisBot bot) throws Exception { 35 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a11.php"; 36 | String parameter = "p=1"; 37 | 38 | String log = "Obtaining the ransom note from the server"; 39 | bot.addLog(log); 40 | 41 | String response = bot.getConnector().post(url, parameter); 42 | String noTags = bot.getEncryptionHandler().untag(response); 43 | String decrypted = bot.getEncryptionHandler().decrypt(noTags); 44 | 45 | String path = bot.getLocalFileSystemManager().writeFile(decrypted.getBytes(), "ransomNote.html"); 46 | log = "The ransom note has been saved to \"" + path + "\""; 47 | bot.addLog(log); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/GetSavedSmsMessages.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import bot.network.Connector; 20 | import anubis.bot.AnubisBot; 21 | import device.SmsMessage; 22 | import java.util.List; 23 | 24 | /** 25 | * Handles the command to get all saves SMS messages from the device 26 | * 27 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 28 | */ 29 | public class GetSavedSmsMessages { 30 | 31 | /** 32 | * Uploads all SMS messages from the device to the C2 33 | * 34 | * @param bot the bot 35 | * @throws Exception if a HTTP request fails 36 | */ 37 | public GetSavedSmsMessages(AnubisBot bot) throws Exception { 38 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a6.php"; 39 | Connector connector = bot.getConnector(); 40 | List inbox = bot.getPhone().getSmsManager().getInbox(); 41 | List drafts = bot.getPhone().getSmsManager().getDrafts(); 42 | List outbox = bot.getPhone().getSmsManager().getOutbox(); 43 | 44 | String result; 45 | String parameter; 46 | 47 | if (outbox.size() > 0) { 48 | result = getSmsFromList(outbox, "sent"); 49 | parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|" + result + "|"); 50 | connector.post(url, parameter); 51 | } 52 | 53 | if (inbox.size() > 0) { 54 | result = getSmsFromList(inbox, "inbox"); 55 | parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|" + result + "|"); 56 | connector.post(url, parameter); 57 | } 58 | 59 | if (drafts.size() > 0) { 60 | result = getSmsFromList(drafts, "draft"); 61 | parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|" + result + "|"); 62 | connector.post(url, parameter); 63 | } 64 | } 65 | 66 | /** 67 | * Gets all SMS messages from a list, for a given folder, in the format that 68 | * Anubis requires 69 | * 70 | * @param list the list of SMS messages 71 | * @param folder the folder to use, being "inbox", "sent", or "draft" 72 | * @return the text messages in the Anubis format 73 | */ 74 | private String getSmsFromList(List list, String folder) { 75 | String result = ""; 76 | 77 | if (folder.equals("inbox")) { 78 | result = "-----INBOX-----"; 79 | } else if (folder.equals("sent")) { 80 | result = "-----SENT-----"; 81 | } else if (folder.equals("draft")) { 82 | result = "-----DRAFT-----"; 83 | } 84 | 85 | for (SmsMessage smsMessage : list) { 86 | result += "\n" + "Number: (" + smsMessage.getRecipient() + ")" + '\n' + "Text: " + smsMessage.getText(); 87 | } 88 | 89 | return result; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/KillBot.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * Handles the bot's termination command 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class KillBot { 27 | 28 | /** 29 | * Handles the bot's termination command 30 | * 31 | * @param bot the bot 32 | */ 33 | public KillBot(AnubisBot bot) { 34 | String log = "Received the command to kill the bot"; 35 | bot.addLog(log); 36 | 37 | bot.getPhone().getSharedPreferences().write("url", ""); 38 | bot.getPhone().getSharedPreferences().write("urls", ""); 39 | bot.getPhone().getSharedPreferences().write("urlInj", ""); 40 | 41 | log = "Emptied \"url\", \"urls\", and \"urlInj\" in the shared preferences"; 42 | bot.addLog(log); 43 | bot.setActive(false); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/OpenActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * Handles the command to open a specific activity 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class OpenActivity { 27 | 28 | /** 29 | * Handles the command to open a specific activity 30 | * 31 | * @param bot the bot 32 | * @param command the command 33 | */ 34 | public OpenActivity(AnubisBot bot, String command) { 35 | String activity = bot.getEncryptionHandler().untag(command, "|openactivity=", "|endactivity"); 36 | 37 | String log = "Received command to open an activity with the name: " + activity; 38 | bot.addLog(log); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/OpenUrlInBrowser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * Handles the command to open a given URL in the browser 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class OpenUrlInBrowser { 27 | 28 | /** 29 | * Handles the command to open a given URL in the browser 30 | * 31 | * @param bot the bot 32 | * @param command the command 33 | */ 34 | public OpenUrlInBrowser(AnubisBot bot, String command) { 35 | String url = bot.getEncryptionHandler().untag(command, "|openbrowser=", "|endbrowser"); 36 | 37 | String log = "Received command to open '" + url + "' in the phone's browser"; 38 | bot.addLog(log); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/RecordSound.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import bot.network.Connector; 20 | import anubis.bot.AnubisBot; 21 | import java.text.DateFormat; 22 | import java.text.SimpleDateFormat; 23 | import java.util.Calendar; 24 | import java.util.Locale; 25 | 26 | /** 27 | * This class handles the command that records a sound 28 | * 29 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 30 | */ 31 | public class RecordSound { 32 | 33 | /** 34 | * This class handles the command that records a sound 35 | * 36 | * @param bot the bot 37 | * @param command the command 38 | */ 39 | public RecordSound(AnubisBot bot, String command) { 40 | String recordDuration = bot.getEncryptionHandler().untag(command, "|recordsound=", "|endrecord"); 41 | String log = "Received command to record sound for " + recordDuration + " seconds"; 42 | bot.addLog(log); 43 | } 44 | 45 | /** 46 | * This function uploads a recording from the disk to the C2 server. 47 | * Currently, m3 does not support emulating recording sounds. If one were to 48 | * implement this function, the skeleton code is given below. 49 | * 50 | * @param bot the bot 51 | * @throws Exception if the HTTP request fails 52 | */ 53 | private void uploadRecording(AnubisBot bot) throws Exception { 54 | DateFormat df = new SimpleDateFormat("MM-dd-yyyy_HH:mm:ss", Locale.US); 55 | String SetTimeString = df.format(Calendar.getInstance().getTime()); 56 | String filename = "RecordSound_" + SetTimeString + ".amr"; 57 | String encoded = ""; //base64 encoded byte[] that is the recording from the disk 58 | 59 | Connector connector = bot.getConnector(); 60 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a13.php"; 61 | String parameters = "p=" + bot.getEncryptionHandler().encrypt(filename + "||:||" + encoded); 62 | String response = connector.post(url, parameters); 63 | response = bot.getEncryptionHandler().decrypt(response); 64 | //Expected result = **good** 65 | if (response.equals("**good**")) { 66 | //remove recording from disk 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/ReplaceUrl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * Handles the command that updates the C2 URL 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class ReplaceUrl { 27 | 28 | /** 29 | * Handles the command that updates the C2 URL 30 | * 31 | * @param bot the bot 32 | * @param command the command 33 | */ 34 | public ReplaceUrl(AnubisBot bot, String command) { 35 | String url = bot.getEncryptionHandler().untag(command, "|replaceurl=", "|endurl"); 36 | String log = "Received new command to replace the bot's C2\n" 37 | + "\tNew C2 URL: " + url; 38 | bot.addLog(log); 39 | bot.getPhone().getSharedPreferences().write("url", url); 40 | bot.getPhone().getSharedPreferences().write("urls", url); 41 | log = "Wrote the new C2 URL to the shared preference keys named \"url\" and \"'urls\""; 42 | bot.addLog(log); 43 | 44 | bot.setServer(url); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/RequestGpsAccessPermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | import device.enums.Permissions; 21 | 22 | /** 23 | * Handles the command to request the GPS permission 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class RequestGpsAccessPermission { 28 | 29 | /** 30 | * Handles the command to request the GPS permission 31 | * 32 | * @param bot the bot 33 | */ 34 | public RequestGpsAccessPermission(AnubisBot bot) { 35 | String title = ""; 36 | String message = ""; 37 | String buttonText = ""; 38 | String locale = bot.getPhone().getLocale(); 39 | if (locale.contains("RU")) { 40 | title = "Геолокация"; 41 | message = "Для корректной работы системы, нужно получить координаты, вам необходимо включить геолокацию"; 42 | buttonText = "Включить сейчас"; 43 | } else if (locale.contains("US")) { 44 | title = "Geolocation"; 45 | message = "For correct operation of the system, you need to get the coordinates, you need to enable geolocation"; 46 | buttonText = "Enable now"; 47 | } else if (locale.contains("TR")) { 48 | title = "Coğrafi konum"; 49 | message = "Sistemin doğru çalışması için, koordinatları almak gerekir, coğrafi konum etkinleştirmeniz gerekir"; 50 | buttonText = "Şimdi etkinleştir"; 51 | } else if (locale.contains("DE")) { 52 | title = "Geolokalisierung"; 53 | message = "Für den korrekten Betrieb des Systems müssen Sie die Koordinaten erhalten, müssen Sie die Geolokalisierung aktivieren"; 54 | buttonText = "Aktivieren Sie jetzt"; 55 | } else if (locale.contains("IT")) { 56 | title = "Geolocalizzazione"; 57 | message = "Per il corretto funzionamento del sistema, è necessario ottenere le coordinate, è necessario abilitare la geolocalizzazione"; 58 | buttonText = "Attiva ora"; 59 | } else if (locale.contains("FR")) { 60 | title = "Géolocalisation"; 61 | message = "Pour un fonctionnement correct du système, vous devez obtenir les coordonnées, vous devez activer la géolocalisation"; 62 | buttonText = "Activer maintenant"; 63 | } else if (locale.contains("UA")) { 64 | title = "Геолокація"; 65 | message = "Для коректної роботи системи вам потрібно, щоб отримати координати, потрібно включити геолокацію"; 66 | buttonText = "Включити зараз"; 67 | } else { 68 | title = "Geolocation"; 69 | message = "For correct operation of the system, you need to get the coordinates, you need to enable geolocation"; 70 | buttonText = "Enable now"; 71 | } 72 | 73 | String log = "Received command to request GPS permission with the following details:\n" 74 | + "\tTitle: " + title + "\n" 75 | + "\tMessage: " + message + "\n" 76 | + "\tButton text: " + buttonText; 77 | bot.addLog(log); 78 | 79 | if (bot.getPhone().getPermissions().contains(Permissions.ACCESS_FINE_LOCATION)) { 80 | log = "The bot already had the GPS permission enabled"; 81 | } else { 82 | log = "The bot was granted the GPS permission"; 83 | bot.getPhone().getPermissions().add(Permissions.ACCESS_FINE_LOCATION); 84 | } 85 | bot.addLog(log); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/RequestUsageAccessPermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | import device.enums.Permissions; 21 | 22 | /** 23 | * Handles the command to request the usage access permission 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class RequestUsageAccessPermission { 28 | 29 | /** 30 | * Handles the command to request the usage access permission 31 | * 32 | * @param bot the bot 33 | */ 34 | public RequestUsageAccessPermission(AnubisBot bot) { 35 | String title = ""; 36 | String message = ""; 37 | String buttonText = ""; 38 | String appName = "[bot app name]"; 39 | String locale = bot.getPhone().getLocale(); 40 | if (locale.contains("RU")) { 41 | title = "Получить разрешение"; 42 | message = "Система не корректно работает, вам необходимо включить доступ к статистике '" + appName + "'"; 43 | buttonText = "Включить сейчас"; 44 | } else if (locale.contains("US")) { 45 | title = "Get permission"; 46 | message = "The system does not work correctly, you need to enable access to the statistics '" + appName + "'"; 47 | buttonText = "Enable now"; 48 | } else if (locale.contains("TR")) { 49 | title = "İzin almak"; 50 | message = "Sistem düzgün çalışmıyor, istatistiklere erişim etkinleştirmeniz gerekir '" + appName + "'"; 51 | buttonText = "Şimdi etkinleştir"; 52 | } else if (locale.contains("DE")) { 53 | title = "Get permission"; 54 | message = "Das system funktioniert nicht richtig, Sie benötigen, um Zugang zu den Statistiken '" + appName + "'"; 55 | buttonText = "Aktivieren Sie jetzt"; 56 | } else if (locale.contains("IT")) { 57 | title = "Ottenere il permesso"; 58 | message = "Il sistema non funziona correttamente, è necessario abilitare l'accesso alle statistiche'" + appName + "'"; 59 | buttonText = "Attiva ora"; 60 | } else if (locale.contains("FR")) { 61 | title = "Obtenir la permission"; 62 | message = "Le système ne fonctionne pas correctement, vous devez activer l'accès aux statistiques'" + appName + "'"; 63 | buttonText = "Activer maintenant"; 64 | } else if (locale.contains("UA")) { 65 | title = "Отримати дозвіл"; 66 | message = "Система не працює коректно, вам необхідно включити доступ до статистики'" + appName + "'"; 67 | buttonText = "Включити зараз"; 68 | } else { 69 | title = "Get permission"; 70 | message = "The system does not work correctly, you need to enable access to the statistics '" + appName + "'"; 71 | buttonText = "Enable now"; 72 | } 73 | 74 | String log = "RReceived command to request usage access permission with the following details:\n" 75 | + "\tTitle: " + title + "\n" 76 | + "\tMessage: " + message + "\n" 77 | + "\tButton text: " + buttonText; 78 | bot.addLog(log); 79 | 80 | if (bot.getPhone().getPermissions().contains(Permissions.PACKAGE_USAGE_STATS)) { 81 | log = "The bot already had the usage access permission enabled"; 82 | } else { 83 | log = "The bot was granted the package usage permission"; 84 | bot.getPhone().getPermissions().add(Permissions.PACKAGE_USAGE_STATS); 85 | } 86 | bot.addLog(log); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/SendGoSms.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import bot.network.Connector; 20 | import anubis.bot.AnubisBot; 21 | 22 | /** 23 | * Handles the command to send a SMS to a given number 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class SendGoSms { 28 | 29 | /** 30 | * Handles the command to send a SMS to a given number 31 | * 32 | * @param bot the bot 33 | * @param command the command 34 | * @throws Exception if the HTTP request fails, or if the command is 35 | * malformed 36 | */ 37 | public SendGoSms(AnubisBot bot, String command) throws Exception { 38 | String number = bot.getEncryptionHandler().untag(command, "|number=", "|text="); 39 | String text = command.split("text=")[1]; 40 | 41 | String log = "Received a command to send a SMS to " + number + " with \"" + text + "\" as text"; 42 | bot.addLog(log); 43 | 44 | Connector connector = bot.getConnector(); 45 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a6.php"; 46 | 47 | String parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|Outgoing SMS" + '\n' + "Number: " + number + '\n' + "Text: " + text + '\n' + "|"); 48 | String response = connector.post(url, parameter); 49 | 50 | log = "Responded to the server that the SMS was sent succesfully, to which the server replied with: \"" + response + "\""; 51 | bot.addLog(log); 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/SendPushNotification.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * Handles the command to send a push notification 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class SendPushNotification { 27 | 28 | /** 29 | * Handles the command to send a push notification 30 | * 31 | * @param bot the bot 32 | * @param command the command 33 | */ 34 | public SendPushNotification(AnubisBot bot, String command) { 35 | String title = bot.getEncryptionHandler().untag(command, "|title=", "|text="); 36 | String text = bot.getEncryptionHandler().untag(command, "|text=", "|icon="); 37 | String icon = command.split("icon=")[1]; 38 | String iconUrl = bot.getServer() + "/icon/" + icon + ".png"; 39 | 40 | String log = "Command to show a push notification received with:\n" 41 | + "\tTitle: " + title + "\n" 42 | + "\tText: " + text + "\n" 43 | + "\tIcon: " + icon + "\n" 44 | + "Icon url: " + iconUrl; 45 | 46 | bot.addLog(log); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/SendSmsMessagesViaPhoneContacts.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import bot.network.Connector; 20 | import anubis.bot.AnubisBot; 21 | import device.Contact; 22 | 23 | /** 24 | * This class handles the command to send a given text message to all contacts 25 | * 26 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 27 | */ 28 | public class SendSmsMessagesViaPhoneContacts { 29 | 30 | /** 31 | * This class handles the command to send a given text message to all 32 | * contacts 33 | * 34 | * @param bot the bot 35 | * @param command the command 36 | * @throws Exception if a HTTP request fails 37 | */ 38 | public SendSmsMessagesViaPhoneContacts(AnubisBot bot, String command) throws Exception { 39 | String message = bot.getEncryptionHandler().untag(command, "|telbookgotext=", "|endtextbook"); 40 | 41 | String log = "Received command to send a text message to all contacts:\n" 42 | + "\t" + message; 43 | bot.addLog(log); 44 | 45 | /** 46 | * If the mass sending is successful, the following message is added to 47 | * the bot's log on the C2: 48 | * 49 | * 50 | * "p=" + SF.trafEnCr(SF.ID_B(this) + "|The dispatch was successful, " + 51 | * schet_sws + " SMS sent|")); 52 | * 53 | * Otherwise, the following is added: 54 | * 55 | * "p=" + SF.trafEnCr(SF.ID_B(this) + "|Error sending SMS, maybe there 56 | * are no permission to send!|")); 57 | * 58 | * Both are using gate 4, aka a6.php 59 | */ 60 | int sentSmsCount = 0; //amount of SMS sent 61 | 62 | /** 63 | * Phone numbers are mandatory to match several criteria, as are given 64 | * in the if-statement within th eloop 65 | */ 66 | for (Contact contact : bot.getPhone().getContacts()) { 67 | String phoneNumber = contact.getNumber(); 68 | if ((!phoneNumber.contains("*")) && (!phoneNumber.contains("#")) && (phoneNumber.length() > 7)) { 69 | sentSmsCount++; 70 | } 71 | } 72 | 73 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a6.php"; 74 | Connector connector = bot.getConnector(); 75 | String parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|The dispatch was successful, " + sentSmsCount + " SMS sent|"); 76 | connector.post(url, parameter); 77 | 78 | log = "Responded to the server that " + sentSmsCount + " message(s) were ssent succesfully"; 79 | bot.addLog(log); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/ShowMessageBox.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * Handles the command to show a message to the user 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class ShowMessageBox { 27 | 28 | /** 29 | * Handles the command to display a message to the user 30 | * 31 | * @param bot the bot 32 | * @param command the command 33 | */ 34 | public ShowMessageBox(AnubisBot bot, String command) { 35 | String title = bot.getEncryptionHandler().untag(command, "|title=", "|text="); 36 | String text = command.split("text=")[1]; 37 | 38 | String log = "Received a command to show a messagebox with:\n" 39 | + "\tTitle: " + title + "\n" 40 | + "\tText: " + text; 41 | bot.addLog(log); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/Socks5.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import bot.network.Connector; 20 | import anubis.bot.AnubisBot; 21 | 22 | /** 23 | * Handles the SOCKS-5 proxy command 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class Socks5 { 28 | 29 | /** 30 | * Handles the SOCKS-5 proxy command 31 | * 32 | * @param bot the bot 33 | * @param command the command 34 | * @throws Exception if the HTTP request fails 35 | */ 36 | public Socks5(AnubisBot bot, String command) throws Exception { 37 | String host = bot.getEncryptionHandler().untag(command, "|sockshost=", "|user="); 38 | String user = bot.getEncryptionHandler().untag(command, "|user=", "|pass="); 39 | String password = bot.getEncryptionHandler().untag(command, "|pass=", "|port="); 40 | String port = bot.getEncryptionHandler().untag(command, "|port=", "|endssh"); 41 | 42 | String log = "Received command to start a SOCKS5 server with the following details:\n" 43 | + "\tHost:" + host + "\n" 44 | + "\tUser: " + user + "\n" 45 | + "\tPassword: " + password + "\n" 46 | + "\tPort: " + port; 47 | bot.addLog(log); 48 | 49 | bot.getPhone().getSharedPreferences().write("socks", ""); 50 | log = "Set \"socks\" in the shared preferences to \"\""; 51 | bot.addLog(log); 52 | 53 | //sleep for 8 seconds in-between updates, continue until the stop sign is given 54 | Connector connector = bot.getConnector(); 55 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a6.php"; 56 | String parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|Working Proxy Server, Connection: ssh -L " + port + ":127.0.0.1:" + port + " " + user + "@" + host); 57 | connector.post(url, parameter); 58 | 59 | log = "Responded to the server with all details"; 60 | bot.addLog(log); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/SpamSms.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * Handles the command to spam all contacts with a given message 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class SpamSms { 27 | 28 | /** 29 | * Handles the command to spam all contacts with a given message 30 | * 31 | * @param bot the bot 32 | * @param command the command 33 | */ 34 | public SpamSms(AnubisBot bot, String command) { 35 | String message = bot.getEncryptionHandler().untag(command, "|spam=", "|endspam"); 36 | 37 | String log = "Received command to spam all contacts with:\n" 38 | + "\t" + message; 39 | bot.addLog(log); 40 | 41 | bot.getPhone().getSharedPreferences().write("textSPAM", message); 42 | bot.getPhone().getSharedPreferences().write("spamSMS", "start"); 43 | bot.getPhone().getSharedPreferences().write("indexSMSSPAM", ""); 44 | 45 | log = "Wrote three values to the shared preferences:\n" 46 | + "\t'textSPAM': " + message + "\n" 47 | + "\t'spamSMS' : 'start'\n" 48 | + "\t'indexSMSSPAM' : \"\""; 49 | bot.addLog(log); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/StartAccessibilityService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | import device.enums.Permissions; 21 | 22 | /** 23 | * This class handles the request for the accessibility service 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class StartAccessibilityService { 28 | 29 | /** 30 | * This class handles the request for the accessibility service 31 | * 32 | * @param bot the bot 33 | */ 34 | public StartAccessibilityService(AnubisBot bot) { 35 | String log = "Received command to start the accessibility service"; 36 | bot.addLog(log); 37 | 38 | String permission = bot.getPhone().getSharedPreferences().read("startRequest"); 39 | 40 | if (permission.contains("Access=0")) { 41 | permission = permission.replace("Access=0", "Access=1"); 42 | bot.getPhone().getSharedPreferences().write("startRequest", permission); 43 | 44 | log = "Replaced 'Access=0' to 'Access=1' in shared preference key 'startRequests'"; 45 | bot.addLog(log); 46 | 47 | if (bot.getPhone().getPermissions().contains(Permissions.BIND_ACCESSIBILITY_SERVICE)) { 48 | log = "The bot was already granted the accessibility service permission"; 49 | } else { 50 | bot.getPhone().getPermissions().add(Permissions.BIND_ACCESSIBILITY_SERVICE); 51 | log = "Granted the accessibility service permission to the bot"; 52 | } 53 | bot.addLog(log); 54 | 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/StartApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * This class handles the command to start a given application 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class StartApplication { 27 | 28 | /** 29 | * This class handles the command to start a given application 30 | * 31 | * @param bot the bot 32 | * @param command the command 33 | */ 34 | public StartApplication(AnubisBot bot, String command) { 35 | String appname = bot.getEncryptionHandler().untag(command, "|startapplication=", "|endapp"); 36 | String log = "Received command to start an application with the name: " + appname; 37 | bot.addLog(log); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/StartInj.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * This class handles the command to start the injection for a (group of) 23 | * targets 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class StartInj { 28 | 29 | /** 30 | * This class handles the command to tart the injection for a (group of) 31 | * targets 32 | * 33 | * @param bot the bot 34 | * @param command 35 | */ 36 | public StartInj(AnubisBot bot, String command) { 37 | String lock_inj = bot.getEncryptionHandler().untag(command, "|startinj=", "|endstartinj"); 38 | 39 | String log = "Command recieved to inject for " + lock_inj; //can be found in ActivityInjection.java in the bot, which uses these values to determine what to steal 40 | bot.addLog(log); 41 | 42 | bot.getPhone().getSharedPreferences().write("lock_inj", lock_inj); 43 | 44 | log = "Wrote the injection request into the shared preferences under 'lock_inj'"; 45 | bot.addLog(log); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/StartPermissions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * This class handles the incoming request to obtain all required permissions 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class StartPermissions { 27 | 28 | /** 29 | * This class handles the incoming request to obtain all required 30 | * permissions 31 | * 32 | * @param bot the bot 33 | */ 34 | public StartPermissions(AnubisBot bot) { 35 | String log = "Received command to start requesting the permissions"; 36 | bot.addLog(log); 37 | 38 | String permission = bot.getPhone().getSharedPreferences().read("startRequest"); 39 | 40 | if (permission.contains("Perm=0")) { 41 | permission = permission.replace("Perm=0", "Perm=1"); 42 | bot.getPhone().getSharedPreferences().write("startRequest", permission); 43 | 44 | log = "Replaced \"Perm=0\" to \"'Perm=1\" in shared preference key \"startRequests\""; 45 | bot.addLog(log); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/StartRat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * This class handles the start of the RAT capability of the bot 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class StartRat { 27 | 28 | /** 29 | * This class handles the start of the RAT capability of the bot 30 | * 31 | * @param bot the bot 32 | * @param command the command 33 | */ 34 | public StartRat(AnubisBot bot, String command) { 35 | String websocket = bot.getEncryptionHandler().untag(command, "|endrat=", "|endurl"); 36 | 37 | String log = "Received command to start the RAT with websocket: " + websocket; 38 | bot.addLog(log); 39 | 40 | bot.getPhone().getSharedPreferences().write("websocket", websocket); 41 | 42 | log = "Changed 'websocket' to " + websocket + " in the shared preferences"; 43 | bot.addLog(log); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/StartUssd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import bot.network.Connector; 20 | import anubis.bot.AnubisBot; 21 | import java.net.URI; 22 | import java.net.URISyntaxException; 23 | 24 | /** 25 | * This class handles the execution of a given USSD command 26 | * 27 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 28 | */ 29 | public class StartUssd { 30 | 31 | /** 32 | * This class handles the execution of a given USSD command 33 | * 34 | * @param bot the bot 35 | * @param command the command 36 | * @throws URISyntaxException if the given USSD is not a valid URI 37 | * @throws Exception if the HTTP request fails 38 | */ 39 | public StartUssd(AnubisBot bot, String command) throws Exception { 40 | String ussd = bot.getEncryptionHandler().untag(command, "|ussd=", "|endUssD"); 41 | ussd = ussd.replace("AAA", "#"); 42 | 43 | String log = "Recieved USSD command: \"" + ussd + "\""; 44 | bot.addLog(log); 45 | 46 | ussd = new URI(ussd).toString(); 47 | String url = bot.getServer() + "/" + bot.getServerFolder() + "/a6.php"; 48 | 49 | Connector connector = bot.getConnector(); 50 | String parameter = "p=" + bot.getEncryptionHandler().encrypt(bot.getPhone().getImei() + "|Request USSD is executed (" + ussd + ")|"); 51 | 52 | log = "Responded to the server that the USSD command (" + ussd + ") has been executed successfully"; 53 | bot.addLog(log); 54 | 55 | connector.post(url, parameter); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/anubis/commands/StopSocks5.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package anubis.commands; 18 | 19 | import anubis.bot.AnubisBot; 20 | 21 | /** 22 | * This class handles the stopping of the SOCKS proxy 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class StopSocks5 { 27 | 28 | /** 29 | * This class handles the stopping of the SOCKs proxy 30 | * 31 | * @param bot 32 | */ 33 | public StopSocks5(AnubisBot bot) { 34 | String log = "Received command to stop the SOCKS5 proxy"; 35 | bot.addLog(log); 36 | 37 | bot.getPhone().getSharedPreferences().write("socks", "stop"); 38 | 39 | log = "Changed the value of \"socks\" in the shared preferences to \"stop\""; 40 | bot.addLog(log); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/bot/Families.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package bot; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | /** 23 | * This class contains all families that are supported within m3 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class Families { 28 | 29 | /** 30 | * gets all supported families in a list 31 | * 32 | * @return a list of all supported families 33 | */ 34 | public static List getAllFamilies() { 35 | List families = new ArrayList<>(); 36 | families.add(ANUBIS); 37 | families.add(CERBERUS); 38 | return families; 39 | } 40 | 41 | /** 42 | * The name for the Anubis family 43 | */ 44 | public static final String ANUBIS = "ANUBIS"; 45 | 46 | /** 47 | * The name of the Cerberus family 48 | */ 49 | public static final String CERBERUS = "CERBERUS"; 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/bot/IBot.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package bot; 18 | 19 | import java.time.LocalDateTime; 20 | 21 | /** 22 | * This interface is used to have a single interface for all implemented bot 23 | * families, regardless of how many are implemented. The functions that are 24 | * defined here are required for the scheduler to work with the bots.
25 | *
26 | * It also forces the programmer of any additional family implementations to 27 | * adhere to the same format. The abstract bot.Bot class contains the 28 | * backbone of any new added bot, meaning the programmer only has to implement 29 | * the bot's logic, and the framework will take care of the rest. 30 | * 31 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 32 | */ 33 | public interface IBot { 34 | 35 | /** 36 | * This function registers the bot to the C2. If the registration is 37 | * successful, the bot's registered boolean is set to true. 38 | */ 39 | public void register(); 40 | 41 | /** 42 | * This method is used to poll the C2 at the previously specified interval. 43 | * As such, incoming commands will be handled by this function, which can 44 | * use and call different classes and functions, depending on the bot's 45 | * implementation. 46 | */ 47 | public void poll(); 48 | 49 | /** 50 | * This function convers the bot into an IConfig object, which is then saved 51 | * into the local file system's folder as config.json. 52 | */ 53 | public void save(); 54 | 55 | /** 56 | * Adds the given string to the log. The log is printed to the standard 57 | * output, and to the log.txt file in the bot's local file system 58 | * 59 | * @param log the log content to add to the log 60 | */ 61 | public void addLog(String log); 62 | 63 | /** 64 | * Gets the bot's registration status 65 | * 66 | * @return true if the bot is registered at the given C2, false if not 67 | */ 68 | public boolean isRegistered(); 69 | 70 | /** 71 | * Sets the bot's registration status 72 | * 73 | * @param status the status to set 74 | */ 75 | public void setRegistration(boolean status); 76 | 77 | /** 78 | * Gets the bot's interval in seconds 79 | * 80 | * @return the interval in seconds 81 | */ 82 | public int getInterval(); 83 | 84 | /** 85 | * Sets the bot's interval in seconds 86 | * 87 | * @param interval the interval to set 88 | */ 89 | public void setInterval(int interval); 90 | 91 | /** 92 | * Gets the next polling moment 93 | * 94 | * @return the next polling moment 95 | */ 96 | public LocalDateTime getNextPollMoment(); 97 | 98 | /** 99 | * Sets the next polling moment 100 | * 101 | * @param nextPollMoment the next moment to poll 102 | */ 103 | public void setNextPollMoment(LocalDateTime nextPollMoment); 104 | 105 | /** 106 | * Defines if the bot is active 107 | * 108 | * @return true if the bot is active, false if not 109 | */ 110 | public boolean isActive(); 111 | 112 | /** 113 | * Sets the bot's activity status 114 | * 115 | * @param status true if the bot is active, false if not 116 | */ 117 | public void setActive(boolean status); 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/bot/IConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package bot; 18 | 19 | /** 20 | * The interface to use for all configuration objects. Each object should also 21 | * extend the abstract Config class, as that contains the core fields for each 22 | * configuration file. 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public interface IConfig { 27 | 28 | /** 29 | * The bot family, as defined in bot.Families 30 | * 31 | * @return the bot's family 32 | */ 33 | public String getBotFamily(); 34 | 35 | /** 36 | * The full path to the local file system folder 37 | * 38 | * @return the full path to the local file system folder 39 | */ 40 | public String getLocalFileSystem(); 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/bot/cryptography/GenericCryptographyHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package bot.cryptography; 18 | 19 | import org.apache.commons.codec.binary.Base64; 20 | 21 | /** 22 | * This class is used to help with more common functions that are using in the 23 | * encryption and decryption process 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public abstract class GenericCryptographyHandler { 28 | 29 | /** 30 | * The base64 decoder 31 | */ 32 | private Base64 base64; 33 | 34 | /** 35 | * This class is used to help with more common functions that are using in 36 | * the encryption and decryption process 37 | */ 38 | public GenericCryptographyHandler() { 39 | base64 = new Base64(); 40 | } 41 | 42 | /** 43 | * Gets the base64 decoder 44 | * 45 | * @return the base64 decoder 46 | */ 47 | public Base64 getBase64() { 48 | return base64; 49 | } 50 | 51 | /** 52 | * Converts a string into a hexadecimal byte array 53 | * 54 | * @param input the string to convert 55 | * @return the converted string 56 | */ 57 | public byte[] hexStringToByteArray(String input) { 58 | int length = input.length(); 59 | byte[] data = new byte[length / 2]; 60 | for (int i = 0; i < length; i += 2) { 61 | data[i / 2] = (byte) ((Character.digit(input.charAt(i), 16) << 4) 62 | + Character.digit(input.charAt(i + 1), 16)); 63 | } 64 | return data; 65 | } 66 | 67 | /** 68 | * Converts a given byte array into a hexadecimal string 69 | * 70 | * @param bytes the bytes to convert 71 | * @return the converted bytes 72 | */ 73 | public String bytesToHexString(byte[] bytes) { 74 | StringBuffer output = new StringBuffer(bytes.length * 2); 75 | for (byte b : bytes) { 76 | String string = Integer.toString(0xFF & b, 16); 77 | if (string.length() < 2) { 78 | output.append('0'); 79 | } 80 | output.append(string); 81 | } 82 | return output.toString(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/bot/cryptography/Rc4.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package bot.cryptography; 18 | 19 | /** 20 | * This class contains the RC-4 algorithm to encrypt and decrypt data. 21 | * 22 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 23 | */ 24 | public class Rc4 { 25 | 26 | /** 27 | * The sbox 28 | */ 29 | private int[] sbox; 30 | 31 | /** 32 | * The RC-4 key to encrypt and decrypt data 33 | */ 34 | private byte[] key; 35 | 36 | /** 37 | * The length of the sbox 38 | */ 39 | private final int SBOX_LENGTH = 256; 40 | 41 | /** 42 | * This class contains the RC-4 algorithm to encrypt and decrypt data. 43 | * 44 | * @param key the RC-4 key to encrypt and decrypt data 45 | */ 46 | public Rc4(byte[] key) { 47 | this.key = key; 48 | } 49 | 50 | /** 51 | * Decrypts the given value with the key that was given when this object was 52 | * created 53 | * 54 | * @param input the input to decrypt 55 | * @return the decrypted output 56 | */ 57 | public byte[] decrypt(final byte[] input) { 58 | return encrypt(input); 59 | } 60 | 61 | /** 62 | * Encrypts the given value with the key that was given when this object was 63 | * created 64 | * 65 | * @param input the input to encrypt 66 | * @return the encrypted output 67 | */ 68 | public byte[] encrypt(final byte[] input) { 69 | sbox = initialiseSbox(); 70 | byte[] code = new byte[input.length]; 71 | int i = 0; 72 | int j = 0; 73 | for (int n = 0; n < input.length; n++) { 74 | i = (i + 1) % SBOX_LENGTH; 75 | j = (j + sbox[i]) % SBOX_LENGTH; 76 | swap(i, j, sbox); 77 | int rand = sbox[(sbox[i] + sbox[j]) % SBOX_LENGTH]; 78 | code[n] = (byte) (rand ^ (int) input[n]); 79 | } 80 | return code; 81 | } 82 | 83 | /** 84 | * Initialises the sbox 85 | * 86 | * @return the initiliased sbox 87 | */ 88 | private int[] initialiseSbox() { 89 | int[] sbox = new int[SBOX_LENGTH]; 90 | int j = 0; 91 | for (int i = 0; i < SBOX_LENGTH; i++) { 92 | sbox[i] = i; 93 | } 94 | for (int i = 0; i < SBOX_LENGTH; i++) { 95 | j = (j + sbox[i] + key[i % key.length] + SBOX_LENGTH) % SBOX_LENGTH; 96 | swap(i, j, sbox); 97 | } 98 | return sbox; 99 | } 100 | 101 | /** 102 | * Swaps the values at the index of i and j within the given array 103 | * 104 | * @param i index i 105 | * @param j index j 106 | * @param array the array to swap the values at the given indices in 107 | */ 108 | private void swap(int i, int j, int[] array) { 109 | int temp = array[i]; 110 | array[i] = array[j]; 111 | array[j] = temp; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/bot/network/Connector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package bot.network; 18 | 19 | import java.io.BufferedReader; 20 | import java.io.ByteArrayOutputStream; 21 | import java.io.InputStream; 22 | import java.io.InputStreamReader; 23 | import java.io.OutputStream; 24 | import java.net.HttpURLConnection; 25 | import java.net.InetSocketAddress; 26 | import java.net.Proxy; 27 | import java.net.URL; 28 | 29 | /** 30 | * This class abstracts the HTTP connections away from the user. Upon its 31 | * creation, the proxy details are provided. If these are null, then no proxy 32 | * will be used. If these are not null, they will be used as a proxy server for 33 | * each request that is made with that specific instance of the connector. 34 | * 35 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 36 | */ 37 | public class Connector { 38 | 39 | /** 40 | * The address of the proxy server. This value should be null if no proxy 41 | * server should be used 42 | */ 43 | private String proxyAddress; 44 | 45 | /** 46 | * The port of the proxy server. This value should be null if no proxy 47 | * server should be used 48 | */ 49 | private Integer proxyPort; 50 | 51 | /** 52 | * The user-agent to use in the requests 53 | */ 54 | private String userAgent; 55 | 56 | /** 57 | * Creates a HTTP connector to easily send HTTP requests. Every request will 58 | * be sent via the proxy server if the provided values are not null. Both 59 | * values can also be null when creating this object, after which no proxy 60 | * server is used. The argumentless constructor sets these values to null 61 | * automatically. 62 | * 63 | * @param proxyAddress the address of the proxy server 64 | * @param proxyPort the port of the proxy server 65 | * @param userAgent the user-agent to use in the requests 66 | */ 67 | public Connector(String proxyAddress, Integer proxyPort, String userAgent) { 68 | this.proxyAddress = proxyAddress; 69 | this.proxyPort = proxyPort; 70 | } 71 | 72 | /** 73 | * Sends a HTTP POST request to the given URL, with the given parameters, 74 | * and the given user-agent. If a proxy server was provided during the 75 | * initialisation of this object, this request is sent via the proxy server. 76 | * 77 | * @param url the URL to connect to 78 | * @param parameter the POST parameter(s) 79 | * @return the result of the request in the form of a string 80 | * @throws Exception if the connection fails 81 | */ 82 | public String post(String url, String parameter) throws Exception { 83 | String result = ""; 84 | byte[] data = null; 85 | InputStream is = null; 86 | URL urlObject = new URL(url); 87 | HttpURLConnection connection; 88 | if (proxyAddress == null && proxyPort == null) { 89 | connection = (HttpURLConnection) urlObject.openConnection(); 90 | } else { 91 | Proxy webProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, proxyPort)); 92 | connection = (HttpURLConnection) urlObject.openConnection(webProxy); 93 | } 94 | connection.setRequestProperty("User-Agent", userAgent); 95 | connection.setRequestMethod("POST"); 96 | connection.setDoOutput(true); 97 | connection.setDoInput(true); 98 | connection.setRequestProperty("Content-Length", "" + Integer.toString(parameter.getBytes().length)); 99 | OutputStream outputStream = connection.getOutputStream(); 100 | data = parameter.getBytes("UTF-8"); 101 | outputStream.write(data); 102 | int parameterLength = parameter.length(); 103 | data = null; 104 | connection.connect(); 105 | int responseCode = connection.getResponseCode(); 106 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 107 | if (responseCode == 200) { 108 | is = connection.getInputStream(); 109 | 110 | byte[] buffer = new byte[parameterLength + 3000]; 111 | int bytesRead; 112 | while ((bytesRead = is.read(buffer)) != -1) { 113 | byteArrayOutputStream.write(buffer, 0, bytesRead); 114 | } 115 | data = byteArrayOutputStream.toByteArray(); 116 | result = new String(data, "UTF-8"); 117 | } else { 118 | //Result is empty by default, meaning an empty string is returned if the response code is not HTTP OK (status 200) 119 | } 120 | return result; 121 | } 122 | 123 | /** 124 | * Sends a HTTP GET request to the given URL, with the given parameters, and 125 | * the given user-agent. If a proxy server was provided during the 126 | * initialisation of this object, this request is sent via tha proxy server. 127 | * 128 | * @param url the URL to connect to 129 | * @param parameter the GET parameter(s) 130 | * @return the result of the request in the form of a string 131 | * @throws Exception if the connection fails 132 | */ 133 | public String get(String url, String parameter) throws Exception { 134 | URL urlObject = new URL(url); 135 | HttpURLConnection connection; 136 | if (proxyAddress == null && proxyPort == null) { 137 | connection = (HttpURLConnection) urlObject.openConnection(); 138 | } else { 139 | Proxy webProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, proxyPort)); 140 | connection = (HttpURLConnection) urlObject.openConnection(webProxy); 141 | } 142 | connection.setRequestProperty("User-Agent", userAgent); 143 | connection.setRequestMethod("GET"); 144 | 145 | StringBuilder content = new StringBuilder(); 146 | try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { 147 | String line; 148 | while ((line = in.readLine()) != null) { 149 | content.append(line); 150 | content.append(System.lineSeparator()); 151 | } 152 | } 153 | return content.toString(); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/cerberus/bot/CerberusConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.bot; 18 | 19 | import bot.Config; 20 | import bot.IConfig; 21 | import device.Contact; 22 | import device.SharedPreferences; 23 | import device.SmsManager; 24 | import java.time.LocalDateTime; 25 | import java.util.List; 26 | import java.util.Set; 27 | 28 | /** 29 | * The configuration file for Cerberus, which implements the IConfig interface 30 | * and the abstract Config class. The abstract class contains all generic 31 | * fields, meaning only additional values are required to be stored in this 32 | * class. 33 | * 34 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 35 | */ 36 | public class CerberusConfig extends Config implements IConfig { 37 | 38 | /** 39 | * The RC-4 key to encrypt and decrypt data 40 | */ 41 | private String rc4Key; 42 | 43 | /** 44 | * The Cerberus ID, which is a 17 character long string (based on 45 | * [a-z0-9]{17}) that is generated when the configuration is created 46 | */ 47 | private String id; 48 | 49 | /** 50 | * Creates a Cerberus bot based on the given data 51 | * 52 | * @param nextPollMoment the next moment in time to poll 53 | * @param botName the bot's internal name, which is only used locally 54 | * @param botFamily the bot's family 55 | * @param tag the bot's tag 56 | * @param localFileSystem the full path to the local file system folder 57 | * @param imei a fake IMEI number 58 | * @param number a fake phone number 59 | * @param networkOperatorName a fake network operator name 60 | * @param locale an ISO-3166-1 alpha-2 country code 61 | * @param version the phone's fake version, as defined in 62 | * Build.VERSION.RELEASE 63 | * @param model the phone's fake model, as defined in Build.MODEL 64 | * @param product the phone's fake product, as defined in Build.PRODUCT 65 | * @param smsManager the phone's SMS manager 66 | * @param contacts fake contacts 67 | * @param sharedPreferences shared preferences for the phone 68 | * @param permissions the bot's permissions on the phone 69 | * @param installedApplications a list of installed applications on the 70 | * phone 71 | * @param server the C2 server WITHOUT any trailing slashes 72 | * @param oldServers a list of old C2 servers 73 | * @param registered a boolean that defines if the bot is registered 74 | * @param userAgent the user-agent to use when contacting the C2 75 | * @param interval the interval in seconds between the polling moments 76 | * @param rooted a boolean that defines if the phone is rooted 77 | * @param defaultSmsManager the default SMS manager object 78 | * @param deviceAdmin a boolean that defines if the bot has admin privileges 79 | * on the device 80 | * @param locked a boolean that defines if the phone's screen is locked 81 | * @param batteryPercentage the battery percentage of the phone 82 | * @param active a boolean that defines if this bot is active 83 | * @param proxyAddress the address of the proxy server (provide null if no 84 | * proxy should be used) 85 | * @param proxyPort the port of the proxy server (provide null if no proxy 86 | * should be used) 87 | * @param rc4Key the RC-4 key that is used to encrypt and decrypt data 88 | * @param id the ID of the bot 89 | */ 90 | public CerberusConfig(LocalDateTime nextPollMoment, String botName, String botFamily, String tag, String localFileSystem, String imei, String number, String networkOperatorName, String locale, String version, String model, String product, SmsManager smsManager, List contacts, SharedPreferences sharedPreferences, Set permissions, Set installedApplications, String server, List oldServers, boolean registered, String userAgent, int interval, boolean rooted, boolean defaultSmsManager, boolean deviceAdmin, boolean locked, int batteryPercentage, boolean active, String proxyAddress, Integer proxyPort, String rc4Key, String id) { 91 | super(nextPollMoment, botName, botFamily, tag, localFileSystem, imei, number, networkOperatorName, locale, version, model, product, smsManager, contacts, sharedPreferences, permissions, installedApplications, server, oldServers, registered, userAgent, interval, rooted, defaultSmsManager, deviceAdmin, locked, batteryPercentage, active, proxyAddress, proxyPort); 92 | this.rc4Key = rc4Key; 93 | this.id = id; 94 | } 95 | 96 | /** 97 | * Gets the RC-4 key to encrypt and decrypt data 98 | * 99 | * @return the RC-4 key 100 | */ 101 | public String getRc4Key() { 102 | return rc4Key; 103 | } 104 | 105 | /** 106 | * Gets the Cerberus ID, which is a 17 character long string (based on 107 | * [a-z0-9]{17}) that is generated when the configuration is created 108 | * 109 | * @return the ID 110 | */ 111 | public String getId() { 112 | return id; 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/cerberus/bot/CerberusEncryptionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.bot; 18 | 19 | import bot.cryptography.GenericCryptographyHandler; 20 | import bot.cryptography.Rc4; 21 | import java.nio.charset.Charset; 22 | 23 | /** 24 | * This class containers helper functions to handle the encryption and 25 | * decryption of data in the format that Cerberus requires 26 | * 27 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 28 | */ 29 | public class CerberusEncryptionHandler extends GenericCryptographyHandler { 30 | 31 | /** 32 | * The RC-4 key to encrypt and decrypt data 33 | */ 34 | private Rc4 rc4; 35 | 36 | /** 37 | * Creates an instance of this helper class 38 | * 39 | * @param rc4Key the RC-4 key to encrypt and decrypt data 40 | */ 41 | public CerberusEncryptionHandler(String rc4Key) { 42 | this.rc4 = new Rc4(rc4Key.getBytes()); 43 | } 44 | 45 | /** 46 | * Encrypts the given input as is required for Cerberus 47 | * 48 | * @param input the input to encrypt 49 | * @return the encrypted output 50 | */ 51 | public String encrypt(String input) { 52 | byte[] tempByteArray = rc4.encrypt(input.getBytes()); 53 | tempByteArray = bytesToHexString(tempByteArray).getBytes(); 54 | return getBase64().encodeToString(tempByteArray); 55 | } 56 | 57 | /** 58 | * Decrypts the given input as is required for Cerberus 59 | * 60 | * @param input the input to decrypt 61 | * @return the decrypted output 62 | */ 63 | public String decrypt(String input) { 64 | String response = new String(getBase64().decode(input), Charset.forName("UTF-8")); 65 | byte[] byteArray = hexStringToByteArray(response); 66 | byte[] decrypted = rc4.decrypt(byteArray); 67 | String output = new String(decrypted); 68 | return output; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/DeleteApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the deletion of a given application 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class DeleteApplication { 27 | 28 | /** 29 | * This class handles the deletion of a given application 30 | * 31 | * @param bot the bot 32 | * @param packageName the package name of the application that is to be 33 | * removed 34 | */ 35 | public DeleteApplication(CerberusBot bot, String packageName) { 36 | String log = "Received the command to delete the following application: " + packageName; 37 | bot.addLog(log); 38 | 39 | if (bot.getPhone().getInstalledApplications().contains(packageName)) { 40 | bot.getPhone().getInstalledApplications().remove(packageName); 41 | log = "The given package, named\"" + packageName + "\", was installed on this device and has been removed"; 42 | bot.addLog(log); 43 | } 44 | 45 | bot.getPhone().getSharedPreferences().write("autoClick", "1"); 46 | bot.getPhone().getSharedPreferences().write("killApplication", packageName); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/ForwardCall.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the command that forwards all incoming calls 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class ForwardCall { 27 | 28 | /** 29 | * This class handles the command that forwards all incoming calls 30 | * 31 | * @param bot the bot 32 | * @param number the number to forward to 33 | */ 34 | public ForwardCall(CerberusBot bot, String number) { 35 | String logForward = "ForwardCALL: " + number + "::endLog::"; 36 | bot.getPhone().getSharedPreferences().append("LogSMS", logForward); 37 | 38 | bot.addLog("Started forwarding incoming calls to: \"" + number + "\""); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/GetContacts.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | import device.Contact; 21 | 22 | /** 23 | * This class handles the command that uploads all contacts to the C2 server 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class GetContacts { 28 | 29 | /** 30 | * This class handles the command that uploads all contacts to the C2 server 31 | * 32 | * @param bot the bot 33 | */ 34 | public GetContacts(CerberusBot bot) { 35 | String phoneNumber = ""; 36 | 37 | for (Contact contact : bot.getPhone().getContacts()) { 38 | String number = contact.getNumber(); 39 | String name = contact.getName(); 40 | if ((!number.contains("*")) && (!number.contains("#")) && (number.length() > 6) && (!phoneNumber.contains(number))) { 41 | phoneNumber = phoneNumber + number + " / " + name + ":end:"; 42 | } 43 | } 44 | 45 | bot.getPhone().getSharedPreferences().write("logsContacts", phoneNumber); 46 | 47 | bot.addLog("Received command to get all contacts and wrote them to the shared preference key named \"logsContacts\", from where they will be uploaded later on"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/GetInstalledApps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the command that gathers all the package names of 23 | * installed applications to the C2 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class GetInstalledApps { 28 | 29 | /** 30 | * This class handles the command that gathers all the package names of 31 | * installed applications to the C2 32 | * 33 | * @param bot the bot 34 | */ 35 | public GetInstalledApps(CerberusBot bot) { 36 | String logs = ""; 37 | for (String packageName : bot.getPhone().getInstalledApplications()) { 38 | logs = logs + packageName + ":end:"; 39 | } 40 | bot.getPhone().getSharedPreferences().write("logsApplications", logs); 41 | 42 | bot.addLog("Received the command to get a list of all installed applications and wrote them to the shared preference key named \"logsApplications\", from where they will be uploaded later on"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/GetSms.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | import device.SmsMessage; 21 | import java.util.List; 22 | 23 | /** 24 | * This command prepares all SMS messages on the phone for the upcoming upload 25 | * 26 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 27 | */ 28 | public class GetSms { 29 | 30 | /** 31 | * This command prepares all SMS messages on the phone for the upcoming 32 | * upload 33 | * 34 | * @param bot the bot 35 | */ 36 | public GetSms(CerberusBot bot) { 37 | String logs = ""; 38 | List sent = bot.getPhone().getSmsManager().getOutbox(); 39 | List inbox = bot.getPhone().getSmsManager().getInbox(); 40 | List drafts = bot.getPhone().getSmsManager().getDrafts(); 41 | 42 | for (SmsMessage smsMessage : sent) { 43 | logs = logs + "~" + "sms/sent" + "~" + "number: " + smsMessage.getRecipient() + " text: " + smsMessage.getText() + ":end:"; 44 | } 45 | 46 | for (SmsMessage smsMessage : inbox) { 47 | logs = logs + "~" + "sms/inbox" + "~" + "number: " + smsMessage.getRecipient() + " text: " + smsMessage.getText() + ":end:"; 48 | } 49 | 50 | for (SmsMessage smsMessage : drafts) { 51 | logs = logs + "~" + "sms/draft" + "~" + "number: " + smsMessage.getRecipient() + " text: " + smsMessage.getText() + ":end:"; 52 | } 53 | 54 | bot.getPhone().getSharedPreferences().write("logsSavedSMS", logs); 55 | 56 | bot.addLog("Received the command to get all text messages from the inbox, draft, and sent folder. The output is written to the shared preference named \"logsSavedSMS\", from where they will be uploaded later on"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/KillMe.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the removal of the bot 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class KillMe { 27 | 28 | /** 29 | * This class handles the removal of the bot 30 | * 31 | * @param bot the bot 32 | */ 33 | public KillMe(CerberusBot bot) { 34 | bot.addLog("The command to deactivate the bot has been received"); 35 | 36 | bot.getPhone().getSharedPreferences().write("autoClick", "1"); 37 | bot.getPhone().getSharedPreferences().write("killApplication", "self"); 38 | 39 | bot.setActive(false); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/OpenUrl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the opening of an URL 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class OpenUrl { 27 | 28 | /** 29 | * This class handles the opening of an URL 30 | * 31 | * @param bot the bot 32 | * @param url the URL to open 33 | */ 34 | public OpenUrl(CerberusBot bot, String url) { 35 | String log = "Received command to open the following URL: \"" + url + "\""; 36 | bot.addLog(log); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/SendNotification.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the command to send a notification to the user 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class SendNotification { 27 | 28 | /** 29 | * This class handles the command to send a notification to the user 30 | * 31 | * @param bot the bot 32 | * @param application the application 33 | * @param title the notification title 34 | * @param text the notification text 35 | */ 36 | public SendNotification(CerberusBot bot, String application, String title, String text) { 37 | bot.getPhone().getSharedPreferences().write("startpush", application); 38 | 39 | String log = "Command to show a push notification received with:\n" 40 | + "\tApplication: " + application + "\n" 41 | + "\tTitle: " + title + "\n" 42 | + "\tText: " + text + "\n"; 43 | bot.addLog(log); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/SendSms.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the command to send a SMS to the given number 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class SendSms { 27 | 28 | /** 29 | * This class handles the command to send a SMS to the given number 30 | * 31 | * @param bot the bot 32 | * @param number the number to send the message to 33 | * @param text the text to send 34 | */ 35 | public SendSms(CerberusBot bot, String number, String text) { 36 | String logSMS = "Output SMS:" + number + " text:" + text + "::endLog::"; 37 | bot.getPhone().getSharedPreferences().append("LogSMS", logSMS); 38 | 39 | bot.addLog("Received a command to send a SMS to " + number + " with \"" + text + "\" as text"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/SendSmsAll.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | import device.Contact; 21 | 22 | /** 23 | * This class handles the command to send a given text message to all contacts 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class SendSmsAll { 28 | 29 | /** 30 | * This class handles the command to send a given text message to all 31 | * contacts 32 | * 33 | * @param bot the bot 34 | * @param text the text message's body 35 | */ 36 | public SendSmsAll(CerberusBot bot, String text) { 37 | String log = "Received the command to send a text message to all contacts. The given message is:\n" 38 | + "\t" + text; 39 | bot.addLog(log); 40 | 41 | for (Contact contact : bot.getPhone().getContacts()) { 42 | String logSMS = "Output SMS:" + contact.getNumber() + " text:" + text + "::endLog::"; 43 | bot.getPhone().getSharedPreferences().append("LogSMS", logSMS); 44 | } 45 | 46 | bot.addLog("Wrote the SMS sending output to the shared preference key named \"LogSMS\", which will be uploaded later on"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/StartAdmin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the command that sets the setting to request the 23 | * administrative privileges 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class StartAdmin { 28 | 29 | /** 30 | * This class handles the command that sets the setting to request the 31 | * administrative privileges 32 | * 33 | * @param bot the bot 34 | */ 35 | public StartAdmin(CerberusBot bot) { 36 | bot.getPhone().getSharedPreferences().write("start_admin", "1"); 37 | 38 | bot.addLog("Received the command to get admin rights on the device. The shared preference key that relates to this, named \"start_admin\", has been changed to \"1\" subsequently"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/StartApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the command to start a given application 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class StartApplication { 27 | 28 | /** 29 | * This class handles the command to start a given application 30 | * 31 | * @param bot the bot 32 | * @param packageName the package name to start 33 | */ 34 | public StartApplication(CerberusBot bot, String packageName) { 35 | String log = "Received the command to start \"" + packageName + "\""; 36 | bot.addLog(log); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/StartAuthenticator2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the command to start the Authenticator2 application 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class StartAuthenticator2 { 27 | 28 | /** 29 | * This class handles the command to start the Authenticator2 application 30 | * 31 | * @param bot the bot 32 | */ 33 | public StartAuthenticator2(CerberusBot bot) { 34 | String app = "com.google.android.apps.authenticator2"; 35 | String log = "Received the command to start the Authenticator2 application: \"" + app + "\""; 36 | bot.addLog(log); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/StartInject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the set-up of the injection for a given application 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class StartInject { 27 | 28 | /** 29 | * This class handles the set-up of the injection for a given application 30 | * 31 | * @param bot the bot 32 | * @param appName the application name 33 | */ 34 | public StartInject(CerberusBot bot, String appName) { 35 | String log = "Received command to show the injection for \"" + appName + "\""; 36 | bot.addLog(log); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/StartUssd.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the given USSD command 23 | * 24 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 25 | */ 26 | public class StartUssd { 27 | 28 | /** 29 | * This class handles the given USSD command 30 | * 31 | * @param bot the bot 32 | * @param ussd the given USSD 33 | */ 34 | public StartUssd(CerberusBot bot, String ussd) { 35 | String logUSSD = "USSD: " + ussd + "::endLog::"; 36 | bot.getPhone().getSharedPreferences().append("LogSMS", logUSSD); 37 | 38 | bot.addLog("Recieved USSD command: \"" + ussd + "\""); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/StartViewInject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the incoming command to start the injection with a 23 | * specific view 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class StartViewInject { 28 | 29 | /** 30 | * This class handles the incoming command to start the injection with a 31 | * specific view 32 | * 33 | * @param bot the bot 34 | * @param componentPackage the component's package 35 | * @param componentView the component's view 36 | * @param injectPackage the injection's package 37 | * @param injectName the injection's name 38 | */ 39 | public StartViewInject(CerberusBot bot, String componentPackage, String componentView, String injectPackage, String injectName) { 40 | String log = "Received the command to start the injection with a specific view:\n" 41 | + "\tComponent package name: " + componentPackage 42 | + "\tComponent view: " + componentView 43 | + "\tInjection package: " + injectPackage 44 | + "\tInjection name: " + injectName; 45 | bot.addLog(log); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/UpdateInjectAndListApps.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the command that specifies if the injections should be 23 | * updated 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class UpdateInjectAndListApps { 28 | 29 | /** 30 | * This class handles the command that specifies if the injections should be 31 | * updated 32 | * 33 | * @param bot the bot 34 | */ 35 | public UpdateInjectAndListApps(CerberusBot bot) { 36 | bot.getPhone().getSharedPreferences().write("checkupdateInjection", "1"); 37 | 38 | bot.addLog("Received the command to update the injections and targeted applications list. The shared preference key named \"checkupdateInjection\" has been set to \"1\", which will initiate the download sequence shortly"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/UpdateModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | 21 | /** 22 | * This class handles the command that defines if the bot's module should be 23 | * updated 24 | * 25 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 26 | */ 27 | public class UpdateModule { 28 | 29 | /** 30 | * This class handles the command that defines if the bot's module should be 31 | * updated 32 | * 33 | * @param bot the bot 34 | */ 35 | public UpdateModule(CerberusBot bot) { 36 | bot.getPhone().getSharedPreferences().write("statDownloadModule", "0"); 37 | 38 | bot.addLog("Received the command to download a new module. The shared preference key \"statDownloadModule\" has been set to \"0\", meaning that the module will be downloaded soon"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/cerberus/commands/UpdateSettingsAndCommands.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package cerberus.commands; 18 | 19 | import cerberus.bot.CerberusBot; 20 | import org.apache.commons.codec.binary.Base64; 21 | import org.json.JSONObject; 22 | 23 | /** 24 | * This class updates the settings and handles any command from the C2. The 25 | * logic to handle a command is specified per command in the classes in 26 | * cerberus.commands. 27 | * 28 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 29 | */ 30 | public class UpdateSettingsAndCommands { 31 | 32 | /** 33 | * * This class updates the settings and handles any command from the C2. 34 | * The logic to handle a command is specified per command in the classes in 35 | * cerberus.commands. 36 | * 37 | * @param bot the bot 38 | * @param jsonObject the JSON input from the C2 39 | * @throws Exception if a HTTP request fails 40 | */ 41 | public UpdateSettingsAndCommands(CerberusBot bot, JSONObject jsonObject) throws Exception { 42 | if (jsonObject.getString("this").equals("no_command") && (bot.getPhone().getSharedPreferences().read("checkupdateInjection").equals("1"))) { //downloading injections 43 | bot.addLog("Received no command in the polling, but the bot is set to update the injections"); 44 | 45 | //Gets all applications 46 | String allApplications = ""; 47 | for (String installedApplication : bot.getPhone().getInstalledApplications()) { 48 | allApplications = allApplications + installedApplication + ":"; 49 | } 50 | 51 | //Deletes last character 52 | if (allApplications.length() > 0 && allApplications.charAt(allApplications.length() - 1) == 'x') { 53 | allApplications = allApplications.substring(0, allApplications.length() - 1); 54 | } 55 | 56 | JSONObject jsonCheckInj = new JSONObject(); 57 | jsonCheckInj.put("id", bot.getId()); 58 | jsonCheckInj.put("apps", allApplications); 59 | 60 | String response = bot.sendData("action=injcheck&data=", jsonCheckInj); 61 | bot.addLog("The response from the server when downloading the injections is:\n\n" + response); 62 | 63 | if (!response.equals("||no||") && (!response.isEmpty())) { 64 | String[] arrayInjection = response.split(":"); 65 | for (int i = 0; i < arrayInjection.length; i++) { 66 | if (!arrayInjection[i].isEmpty()) { 67 | bot.getPhone().getSharedPreferences().write(arrayInjection[i], "");//html fake app 68 | bot.getPhone().getSharedPreferences().write("icon_" + arrayInjection[i], "");//icon 69 | 70 | bot.addLog("Added \"" + arrayInjection[i] + "\" to the shared preferences"); 71 | } 72 | } 73 | bot.getPhone().getSharedPreferences().write("arrayInjection", response); 74 | bot.getPhone().getSharedPreferences().write("checkupdateInjection", ""); 75 | bot.getPhone().getSharedPreferences().write("whileStartUpdateInection", "1"); 76 | } 77 | } else if (jsonObject.getString("this").equals("~settings~")) { 78 | String temp = ""; 79 | 80 | bot.getPhone().getSharedPreferences().write("idSettings", jsonObject.getString("saveID")); 81 | 82 | if (jsonObject.getString("arrayUrl").length() > 7) { 83 | bot.getPhone().getSharedPreferences().write("urls", bot.getPhone().getSharedPreferences().read("urlAdminPanel") + "," + jsonObject.getString("arrayUrl")); 84 | temp += "\tKey: \"urls\" was appended with \"" + jsonObject.getString("arrayUrl") + "\"\n"; 85 | } 86 | if (bot.getPhone().getSharedPreferences().read("timeInject").equals("-1")) { 87 | bot.getPhone().getSharedPreferences().write("timeInject", jsonObject.getString("timeInject")); 88 | temp += "\tKey: \"timeInject\" was changed to \"" + jsonObject.getString("timeInject") + "\"\n"; 89 | } 90 | if (bot.getPhone().getSharedPreferences().read("timeCC").equals("-1")) { 91 | bot.getPhone().getSharedPreferences().write("timeCC", jsonObject.getString("timeCC")); 92 | temp += "\tKey: \"timeCC\" was changed to \"" + jsonObject.getString("timeCC") + "\"\n"; 93 | } 94 | if (bot.getPhone().getSharedPreferences().read("timeMails").equals("-1")) { 95 | bot.getPhone().getSharedPreferences().write("timeMails", jsonObject.getString("timeMail")); 96 | temp += "\tKey: \"timeMails\" was changed to \"" + jsonObject.getString("timeMail") + "\"\n"; 97 | } 98 | if (bot.getPhone().getSharedPreferences().read("timeProtect").equals("-1")) { 99 | bot.getPhone().getSharedPreferences().write("timeProtect", jsonObject.getString("timeProtect")); 100 | temp += "\tKey: \"timeProtect\" was changed to \"" + jsonObject.getString("timeProtect") + "\"\n"; 101 | } 102 | 103 | if (temp.isEmpty() == false) { 104 | String settingsUpdate = "Updated one or more shared preference values, as can be seen below:\n" + temp; 105 | //Removes the last newly from the items, thus avoiding an empty line in the log file 106 | settingsUpdate = settingsUpdate.substring(0, settingsUpdate.length() - 1); 107 | bot.addLog(settingsUpdate); 108 | } 109 | 110 | } else if (jsonObject.getString("this").equals("~mySettings~")) { 111 | bot.getPhone().getSharedPreferences().write("hiddenSMS", jsonObject.getString("hideSMS")); // + 112 | bot.getPhone().getSharedPreferences().write("lockDevice", jsonObject.getString("lockDevice"));// + 113 | bot.getPhone().getSharedPreferences().write("offSound", jsonObject.getString("offSound"));// + 114 | bot.getPhone().getSharedPreferences().write("keylogger", jsonObject.getString("keylogger"));// + 115 | bot.getPhone().getSharedPreferences().write("actionSettingInection", jsonObject.getString("activeInjection"));// + 116 | 117 | String mySettingsUpdate = "Updated several shared preference values, as can be seen below:\n" 118 | + "\tKey: \"hiddenSMS\" with value \"" + jsonObject.getString("hideSMS") + "\"\n" 119 | + "\tKey: \"lockDevice\" with value \"" + jsonObject.getString("lockDevice") + "\"\n" 120 | + "\tKey: \"offSound\" with value \"" + jsonObject.getString("offSound") + "\"\n" 121 | + "\tKey: \"keylogger\" with value \"" + jsonObject.getString("keylogger") + "\"\n" 122 | + "\tKey: \"actionSettingInection\" with value \"" + jsonObject.getString("activeInjection") + "\""; 123 | bot.addLog(mySettingsUpdate); 124 | } else if (jsonObject.getString("this").equals("~commands~")) { 125 | byte[] byteData = new Base64().decode(jsonObject.getString("data")); 126 | JSONObject jsonCommand = new JSONObject(new String(byteData, "UTF-8")); 127 | switch (jsonCommand.getString("name")) { 128 | case "sendSms": 129 | new SendSms(bot, jsonCommand.getString("number"), jsonCommand.getString("text")); 130 | break; 131 | case "startUssd": 132 | new StartUssd(bot, jsonCommand.getString("ussd")); 133 | break; 134 | case "forwardCall": 135 | new ForwardCall(bot, jsonCommand.getString("number")); 136 | break; 137 | case "push": 138 | //SettingsWrite(mContext, "startpush", app); 139 | new SendNotification(bot, jsonCommand.getString("app"), jsonCommand.getString("title"), jsonCommand.getString("text")); 140 | break; 141 | case "getContacts": 142 | new GetContacts(bot); 143 | case "getInstallApps": 144 | new GetInstalledApps(bot); 145 | break; 146 | case "getSMS": 147 | new GetSms(bot); 148 | break; 149 | case "startInject": 150 | new StartInject(bot, jsonCommand.getString("app")); 151 | break; 152 | case "openUrl": 153 | new OpenUrl(bot, jsonCommand.getString("url")); 154 | break; 155 | case "startAuthenticator2": 156 | new StartAuthenticator2(bot); 157 | break; 158 | case "SendSMSALL": 159 | new SendSmsAll(bot, jsonCommand.getString("text")); 160 | break; 161 | case "startApp": 162 | new StartApplication(bot, jsonCommand.getString("app")); 163 | break; 164 | case "deleteApplication": 165 | new DeleteApplication(bot, jsonCommand.getString("app")); 166 | break; 167 | case "startAdmin": 168 | new StartAdmin(bot); 169 | break; 170 | case "killMe": 171 | new KillMe(bot); 172 | break; 173 | case "updateInjectAndListApps": 174 | new UpdateInjectAndListApps(bot); 175 | break; 176 | case "updateModule": 177 | new UpdateModule(bot); 178 | break; 179 | } 180 | } 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/config/ConfigHelperCli.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package config; 18 | 19 | import bot.Families; 20 | import java.io.IOException; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import org.apache.commons.cli.CommandLine; 24 | 25 | /** 26 | * This class containers helper functions that are used when a user attempts to 27 | * create a config file using the command-line interface 28 | * 29 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 30 | */ 31 | public class ConfigHelperCli { 32 | 33 | /** 34 | * This function contains all required arguments 35 | * 36 | * @return a list of all arguments in shorthand form 37 | */ 38 | private List getAllArguments() { 39 | List arguments = new ArrayList<>(); 40 | arguments.add("bf"); 41 | arguments.add("bn"); 42 | arguments.add("t"); 43 | arguments.add("lfs"); 44 | 45 | arguments.add("i"); 46 | arguments.add("n"); 47 | arguments.add("op"); 48 | arguments.add("lo"); 49 | arguments.add("v"); 50 | arguments.add("m"); 51 | arguments.add("p"); 52 | arguments.add("smsI"); 53 | arguments.add("smsD"); 54 | arguments.add("smsO"); 55 | arguments.add("c"); 56 | arguments.add("perm"); 57 | arguments.add("apps"); 58 | arguments.add("c2"); 59 | arguments.add("ua"); 60 | arguments.add("r"); 61 | arguments.add("man"); 62 | arguments.add("int"); 63 | arguments.add("da"); 64 | arguments.add("scrn"); 65 | arguments.add("bp"); 66 | return arguments; 67 | } 68 | 69 | /** 70 | * This function checks if the given Apache CommandLine object contains all 71 | * required arguments 72 | * 73 | * @param cli the Apache CommandLine object that contains all received 74 | * command-line arguments 75 | * @return a list of missing arguments in shorthand form 76 | */ 77 | protected List containsAllArguments(CommandLine cli) { 78 | List arguments = getAllArguments(); 79 | 80 | //Add family specific arguments 81 | if (cli.hasOption("bf")) { 82 | String botFamily = cli.getOptionValue("bf"); 83 | if (botFamily.equalsIgnoreCase(Families.ANUBIS) || botFamily.equalsIgnoreCase(Families.CERBERUS)) { 84 | arguments.add("rc4"); 85 | } 86 | if (botFamily.equalsIgnoreCase(Families.ANUBIS)) { 87 | arguments.add("sf"); 88 | } 89 | } 90 | 91 | List missingArguments = new ArrayList<>(); 92 | 93 | for (String argument : arguments) { 94 | if (cli.hasOption(argument) == false) { 95 | missingArguments.add(argument); 96 | } 97 | } 98 | return missingArguments; 99 | } 100 | 101 | /** 102 | * This function is used to obtain a boolean based on specific user-input. 103 | * To return true, this function requires "true", "t", "yes", or "y" as 104 | * input. To return false, this function requires "false", "f", "no", or 105 | * "n". If none of these options can be found, an exception is thrown with 106 | * an error message. 107 | * 108 | * @param input the input to check 109 | * @return to return true, this function requires "true", "t", "yes", or "y" 110 | * as input. To return false, this function requires "false", "f", "no", or 111 | * "n" 112 | * @throws IOException if none of these options can be found, an exception 113 | * is thrown with an error message. 114 | */ 115 | protected boolean getBooleanFromCli(String input) throws IOException { 116 | if (input.equalsIgnoreCase("true") || input.equalsIgnoreCase("t") || input.equalsIgnoreCase("yes") || input.equalsIgnoreCase("y")) { 117 | return true; 118 | } else if (input.equalsIgnoreCase("false") || input.equalsIgnoreCase("f") || input.equalsIgnoreCase("no") || input.equalsIgnoreCase("n")) { 119 | return false; 120 | } else { 121 | throw new IOException("[+]ERROR: the given value (\"" + input + "\") is not any of the following: \"true\", \"t\", \"yes\", \"y\", \"false\", \"f\", \"no\", or \"n\""); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/config/ConfigLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package config; 18 | 19 | import anubis.bot.AnubisBot; 20 | import anubis.bot.AnubisConfig; 21 | import bot.Families; 22 | import bot.IBot; 23 | import bot.IConfig; 24 | import cerberus.bot.CerberusBot; 25 | import cerberus.bot.CerberusConfig; 26 | import com.google.gson.Gson; 27 | import device.Phone; 28 | import java.io.File; 29 | import java.io.IOException; 30 | import java.nio.file.Files; 31 | import java.time.LocalDateTime; 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | import org.json.JSONObject; 35 | 36 | /** 37 | * This class is used to load configuration files from files on the disk, and to 38 | * convert configuration files into bot objects. 39 | * 40 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 41 | */ 42 | public class ConfigLoader { 43 | 44 | /** 45 | * Creates a bot for a given configuration object for any of the implemented 46 | * families. If the family name is not found, null is returned 47 | * 48 | * @param config the configuration file to make a bot from 49 | * @return the bot, based on the given config file, or null if there is no 50 | * such family 51 | */ 52 | public IBot loadBot(IConfig config) { 53 | String family = config.getBotFamily(); 54 | if (family.equalsIgnoreCase(Families.ANUBIS)) { 55 | AnubisConfig anubisConfig = (AnubisConfig) config; 56 | Phone phone = new Phone(anubisConfig.getImei(), anubisConfig.getNumber(), anubisConfig.getNetworkOperatorName(), anubisConfig.getLocale(), anubisConfig.getVersion(), anubisConfig.getModel(), anubisConfig.getProduct(), anubisConfig.getSmsManager(), anubisConfig.getContacts(), anubisConfig.getSharedPreferences(), anubisConfig.getPermissions(), anubisConfig.getInstalledApplications(), anubisConfig.getUserAgent(), anubisConfig.isRooted(), anubisConfig.isDeviceAdmin(), anubisConfig.isLocked(), anubisConfig.getBatteryPercentage()); 57 | return new AnubisBot(LocalDateTime.now(), anubisConfig.getBotName(), anubisConfig.getBotFamily(), anubisConfig.getTag(), anubisConfig.getLocalFileSystem(), phone, anubisConfig.getServer(), anubisConfig.getOldServers(), anubisConfig.isRegistered(), anubisConfig.isDefaultSmsManager(), anubisConfig.getInterval(), anubisConfig.isActive(), anubisConfig.getProxyAddress(), anubisConfig.getProxyPort(), anubisConfig.getRc4Key(), anubisConfig.getServerFolder()); 58 | } else if (family.equalsIgnoreCase(Families.CERBERUS)) { 59 | CerberusConfig cerberusConfig = (CerberusConfig) config; 60 | Phone phone = new Phone(cerberusConfig.getImei(), cerberusConfig.getNumber(), cerberusConfig.getNetworkOperatorName(), cerberusConfig.getLocale(), cerberusConfig.getVersion(), cerberusConfig.getModel(), cerberusConfig.getProduct(), cerberusConfig.getSmsManager(), cerberusConfig.getContacts(), cerberusConfig.getSharedPreferences(), cerberusConfig.getPermissions(), cerberusConfig.getInstalledApplications(), cerberusConfig.getUserAgent(), cerberusConfig.isRooted(), cerberusConfig.isDeviceAdmin(), cerberusConfig.isLocked(), cerberusConfig.getBatteryPercentage()); 61 | return new CerberusBot(LocalDateTime.now(), cerberusConfig.getBotName(), cerberusConfig.getBotFamily(), cerberusConfig.getTag(), cerberusConfig.getLocalFileSystem(), phone, cerberusConfig.getServer(), cerberusConfig.getOldServers(), cerberusConfig.isRegistered(), cerberusConfig.isDefaultSmsManager(), cerberusConfig.getInterval(), cerberusConfig.isActive(), cerberusConfig.getProxyAddress(), cerberusConfig.getProxyPort(), cerberusConfig.getRc4Key(), cerberusConfig.getId()); 62 | } 63 | System.out.println("[+]Failed to load a configuration file, details are given below:"); 64 | System.out.println("\tUnknown family name: " + family); 65 | System.out.println("\tUsing the following local file system: " + config.getLocalFileSystem()); 66 | return null; 67 | } 68 | 69 | /** 70 | * Creates bots for the given configuration objects for any of the 71 | * implemented families. If the family name is not found, null is returned 72 | * 73 | * @param configs the list of configuration files to make bots from 74 | * @return the bots, based on the given config files. Bots that cannot be 75 | * loaded are not included in this list. A message to the standard output 76 | * provides clarity for any of the configuration files that could not be 77 | * converted into a bot. 78 | */ 79 | public List loadBots(List configs) { 80 | List bots = new ArrayList<>(); 81 | 82 | for (IConfig config : configs) { 83 | IBot bot = loadBot(config); 84 | if (bot != null) { 85 | bots.add(bot); 86 | } else { 87 | System.out.println("[+]The configuration file that uses \"" + config.getLocalFileSystem() + "\" as a local file system folder cannot be loaded, as the family name (which equals \"" + config.getBotFamily() + "\") cannot be found in the list of implemented bots"); 88 | } 89 | } 90 | 91 | return bots; 92 | } 93 | 94 | /** 95 | * Loads all the given configuration files from the given paths, and creates 96 | * configuration files from the data in each file 97 | * 98 | * @param paths the paths to load the configuration files from 99 | * @return a list of configuration files that could be loaded 100 | */ 101 | public List loadConfigs(List paths) { 102 | List configs = new ArrayList<>(); 103 | 104 | for (String path : paths) { 105 | try { 106 | File file = new File(path); 107 | if (file.exists() == false) { 108 | System.out.println("[+]ERROR: the given path (\"" + path + "\") does not exist, meaning it is ignored"); 109 | continue; 110 | } 111 | 112 | if (file.isDirectory()) { 113 | for (File listFile : file.listFiles()) { 114 | if (listFile.getName().endsWith("config.json") && listFile.isFile()) { 115 | file = listFile; 116 | } 117 | } 118 | } 119 | 120 | String jsonRaw = new String(Files.readAllBytes(file.toPath())); 121 | JSONObject json = new JSONObject(jsonRaw); 122 | 123 | Gson gson = new Gson(); 124 | String family = json.optString("botFamily", ""); 125 | 126 | if (family.equalsIgnoreCase(Families.ANUBIS)) { 127 | configs.add(gson.fromJson(json.toString(), AnubisConfig.class 128 | )); 129 | 130 | } else if (family.equalsIgnoreCase(Families.CERBERUS)) { 131 | configs.add(gson.fromJson(json.toString(), CerberusConfig.class 132 | )); 133 | } else { 134 | System.out.println("[+]No family can be found for \"" + family + "\", located in \"" + path + "\""); 135 | } 136 | } catch (IOException ex) { 137 | System.out.println("[+]ERROR: " + ex.getMessage()); 138 | return new ArrayList<>(); 139 | } 140 | 141 | } 142 | return configs; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/device/Contact.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package device; 18 | 19 | /** 20 | * This class is used to store a fake contact, which is used in the fake phone. 21 | * 22 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 23 | */ 24 | public class Contact { 25 | 26 | /** 27 | * The contact's name 28 | */ 29 | private String name; 30 | 31 | /** 32 | * The contact's number 33 | */ 34 | private String number; 35 | 36 | /** 37 | * This class is used to store a fake contact, which is used in the fake 38 | * phone. 39 | * 40 | * @param name the contact's name 41 | * @param number the contact's number 42 | */ 43 | public Contact(String name, String number) { 44 | this.name = name; 45 | this.number = number; 46 | } 47 | 48 | /** 49 | * Gets the contact's name 50 | * 51 | * @return the name of the contact 52 | */ 53 | public String getName() { 54 | return name; 55 | } 56 | 57 | /** 58 | * Gets the number of the contact 59 | * 60 | * @return the contact's number 61 | */ 62 | public String getNumber() { 63 | return number; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/device/SharedPreferences.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package device; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | 22 | /** 23 | * This class contains the shared preferences, as can be used on Android phones. 24 | * The shared preferences are based upon a HashMap, for which several helper 25 | * functions are available in this class. 26 | * 27 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 28 | */ 29 | public class SharedPreferences { 30 | 31 | /** 32 | * The mapping that stores all shared preferences 33 | */ 34 | private Map preferences; 35 | 36 | /** 37 | * This class contains the shared preferences, as can be used on Android 38 | * phones. The shared preferences are based upon a HashMap, for which 39 | * several helper functions are available in this class. 40 | */ 41 | public SharedPreferences() { 42 | preferences = new HashMap<>(); 43 | } 44 | 45 | /** 46 | * Get the complete mapping 47 | * 48 | * @return the complete mapping 49 | */ 50 | public Map getPreferences() { 51 | return preferences; 52 | } 53 | 54 | /** 55 | * Overwrite all existing preferences in the mapping 56 | * 57 | * @param preferences the new mapping 58 | */ 59 | public void setPreferences(Map preferences) { 60 | this.preferences = preferences; 61 | } 62 | 63 | /** 64 | * Read a specific key from the mapping. If there is no such key, null is 65 | * returned. 66 | * 67 | * @param key the key to read the value for 68 | * @return the value that is present in the mapping for the given key, or 69 | * null if it cannot be found 70 | */ 71 | public String read(String key) { 72 | return preferences.get(key); 73 | } 74 | 75 | /** 76 | * Similar to the read function, this function reads the value from a given 77 | * key. If the key is not present, the default value is returned, rather 78 | * than null. 79 | * 80 | * @param key the key to obtain the value for 81 | * @param defaultValue the value to return in case the key is not present 82 | * @return the value of the key, or the default value if there is no such 83 | * key 84 | */ 85 | public String readOrDefault(String key, String defaultValue) { 86 | return preferences.getOrDefault(key, defaultValue); 87 | } 88 | 89 | /** 90 | * Writes the given value at the given key, overwriting any value that might 91 | * have been there already 92 | * 93 | * @param key the key to write 94 | * @param value the value to write 95 | */ 96 | public void write(String key, String value) { 97 | preferences.put(key, value); 98 | } 99 | 100 | /** 101 | * Removes the key and its associated value from the mapping, if it exists 102 | * 103 | * @param key the key to remove 104 | */ 105 | public void remove(String key) { 106 | preferences.remove(key); 107 | } 108 | 109 | /** 110 | * Appends a given value to the given key. If no such key is present, it is 111 | * created with the given value 112 | * 113 | * @param key the key to work with 114 | * @param value the value to append 115 | */ 116 | public void append(String key, String value) { 117 | String oldValue = preferences.get(key); 118 | if (oldValue == null) { 119 | oldValue = ""; 120 | } 121 | String newValue = oldValue + value; 122 | preferences.put(key, newValue); 123 | } 124 | 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/device/SmsManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package device; 18 | 19 | import java.util.List; 20 | 21 | /** 22 | * This class is part of the device.Phone class, as it functions as the SMS 23 | * manager of the device. It contains three lists with SmsMessage objects. These 24 | * lists represent the inbox, drafts folder, and the outbox of the SMS manager 25 | * of the phone. 26 | * 27 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 28 | */ 29 | public class SmsManager { 30 | 31 | /** 32 | * The list of SMS messages for the inbox 33 | */ 34 | private List inbox; 35 | 36 | /** 37 | * The list of SMS messages for the drafts folder 38 | */ 39 | private List drafts; 40 | 41 | /** 42 | * The list of SMS messages for the outbox 43 | */ 44 | private List outbox; 45 | 46 | /** 47 | * This class is part of the device.Phone class, as it functions as the SMS 48 | * manager of the device. It contains three lists with SmsMessage objects. 49 | * These lists represent the inbox, drafts folder, and the outbox of the SMS 50 | * manager of the phone. 51 | * 52 | * @param inbox the list of SMS messages for the inbox 53 | * @param drafts the list of SMS messages for the drafts folder 54 | * @param outbox the list of SMS messages for the outbox 55 | */ 56 | public SmsManager(List inbox, List drafts, List outbox) { 57 | this.inbox = inbox; 58 | this.drafts = drafts; 59 | this.outbox = outbox; 60 | } 61 | 62 | /** 63 | * The list of SMS messages for the inbox 64 | * 65 | * @return the inbox 66 | */ 67 | public List getInbox() { 68 | return inbox; 69 | } 70 | 71 | /** 72 | * The list of SMS messages for the drafts folder 73 | * 74 | * @return the drafts 75 | */ 76 | public List getDrafts() { 77 | return drafts; 78 | } 79 | 80 | /** 81 | * The list of SMS messages for the outbox 82 | * 83 | * @return the outbox 84 | */ 85 | public List getOutbox() { 86 | return outbox; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/device/SmsMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package device; 18 | 19 | /** 20 | * This class contains two fields for a text message: the recipient, and the 21 | * actual message body. 22 | * 23 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 24 | */ 25 | public class SmsMessage { 26 | 27 | /** 28 | * The recipient of the text message 29 | */ 30 | private String recipient; 31 | 32 | /** 33 | * The text message of the body 34 | */ 35 | private String text; 36 | 37 | /** 38 | * Creates a SmsMessage object with a given recipient and a given text body 39 | * 40 | * @param recipient the recipient of this SMS message 41 | * @param text the text body of this SMS message 42 | */ 43 | public SmsMessage(String recipient, String text) { 44 | this.recipient = recipient; 45 | this.text = text; 46 | } 47 | 48 | /** 49 | * Gets the recipient of this SMS message 50 | * 51 | * @return the recipient 52 | */ 53 | public String getRecipient() { 54 | return recipient; 55 | } 56 | 57 | /** 58 | * Gets the text body of this SMS message 59 | * 60 | * @return the body 61 | */ 62 | public String getText() { 63 | return text; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/device/enums/VersionCodes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package device.enums; 18 | 19 | /** 20 | * 21 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] and 22 | * Google's Android developers [see 23 | * https://developer.android.com/reference/android/os/Build.VERSION_CODES] 24 | */ 25 | public class VersionCodes { 26 | 27 | /** 28 | * The first Android version 29 | */ 30 | public static final int BASE = 1; 31 | 32 | /** 33 | * The first Android update 34 | */ 35 | public static final int BASE_1_1 = 2; 36 | 37 | /** 38 | * Android 1.5. 39 | */ 40 | public static final int CUPCAKE = 3; 41 | 42 | /** 43 | * Android 1.6. 44 | */ 45 | public static final int DONUT = 4; 46 | 47 | /** 48 | * Android 2.0 49 | */ 50 | public static final int ECLAIR = 5; 51 | 52 | /** 53 | * Android 2.0.1 54 | */ 55 | public static final int ECLAIR_0_1 = 6; 56 | 57 | /** 58 | * Android 2.1 59 | */ 60 | public static final int ECLAIR_MR1 = 7; 61 | 62 | /** 63 | * Android 2.2 64 | */ 65 | public static final int FROYO = 8; 66 | 67 | /** 68 | * Android 2.3 69 | */ 70 | public static final int GINGERBREAD = 9; 71 | 72 | /** 73 | * Android 2.3.3. 74 | */ 75 | public static final int GINGERBREAD_MR1 = 10; 76 | 77 | /** 78 | * Android 3.0. 79 | */ 80 | public static final int HONEYCOMB = 11; 81 | 82 | /** 83 | * Android 3.1. 84 | */ 85 | public static final int HONEYCOMB_MR1 = 12; 86 | 87 | /** 88 | * Android 3.2. 89 | */ 90 | public static final int HONEYCOMB_MR2 = 13; 91 | 92 | /** 93 | * Android 4.0. 94 | */ 95 | public static final int ICE_CREAM_SANDWICH = 14; 96 | 97 | /** 98 | * Android 4.0.3. 99 | */ 100 | public static final int ICE_CREAM_SANDWICH_MR1 = 15; 101 | 102 | /** 103 | * Android 4.1. 104 | */ 105 | public static final int JELLY_BEAN = 16; 106 | 107 | /** 108 | * Android 4.2 109 | */ 110 | public static final int JELLY_BEAN_MR1 = 17; 111 | 112 | /** 113 | * Android 4.3 114 | */ 115 | public static final int JELLY_BEAN_MR2 = 18; 116 | 117 | /** 118 | * Android 4.4 119 | */ 120 | public static final int KITKAT = 19; 121 | 122 | /** 123 | * Android 4.4W 124 | */ 125 | public static final int KITKAT_WATCH = 20; 126 | 127 | /** 128 | * Temporary until the switch was made to LOLLIPOP 129 | */ 130 | public static final int L = 21; 131 | 132 | /** 133 | * Lollipop 134 | */ 135 | public static final int LOLLIPOP = 21; 136 | 137 | /** 138 | * Lollipop MR1 139 | */ 140 | public static final int LOLLIPOP_MR1 = 22; 141 | 142 | /** 143 | * Marshmallow 144 | */ 145 | public static final int M = 23; 146 | 147 | /** 148 | * Nougat 149 | */ 150 | public static final int N = 24; 151 | 152 | /** 153 | * N MR1 154 | */ 155 | public static final int N_MR1 = 25; 156 | 157 | /** 158 | * Oreo 159 | */ 160 | public static final int O = 26; 161 | 162 | /** 163 | * Oreo MR1. 164 | */ 165 | public static final int O_MR1 = 27; 166 | 167 | /** 168 | * Android 9 Pie 169 | */ 170 | public static final int P = 28; 171 | 172 | /** 173 | * Android 10 174 | */ 175 | public static final int Q = 29; 176 | 177 | /** 178 | * Android 11 179 | */ 180 | public static final int R = 30; 181 | } 182 | -------------------------------------------------------------------------------- /src/main/java/emulator/Emulator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package emulator; 18 | 19 | import config.ConfigCreator; 20 | import scheduler.BotScheduler; 21 | import bot.IConfig; 22 | import java.util.ArrayList; 23 | import java.util.Arrays; 24 | import java.util.List; 25 | import config.ConfigLoader; 26 | import org.apache.commons.cli.CommandLine; 27 | import org.apache.commons.cli.CommandLineParser; 28 | import org.apache.commons.cli.DefaultParser; 29 | import org.apache.commons.cli.HelpFormatter; 30 | import org.apache.commons.cli.Options; 31 | import org.apache.commons.cli.ParseException; 32 | 33 | /** 34 | * This class contains the entry point of the m3 framework. Its purpose is to 35 | * handle the command-line input and select the correct module. A module might 36 | * have an additional command-line interface, which is left up to the 37 | * implementation of said module. 38 | * 39 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 40 | */ 41 | public class Emulator { 42 | 43 | /** 44 | * The main class requires some command-line interface arguments to work. If 45 | * no recognised options are present, the help menu will be shown 46 | * 47 | * @param args the command line arguments 48 | */ 49 | public static void main(String[] args) { 50 | //Prints the version information 51 | System.out.println("[+]Mobile Malware Mimicking (m3) version 1.0-stable by Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl]"); 52 | System.out.println("\tBy using this framework you acknowledge that you are only providing details to bots that you fully own!"); 53 | 54 | //Initialise the required Apache objects 55 | CommandLineParser parser = new DefaultParser(); 56 | HelpFormatter formatter = new HelpFormatter(); 57 | 58 | //Initialise the required m3 objects 59 | ConfigCreator configCreator = new ConfigCreator(); 60 | BotScheduler scheduler = new BotScheduler(); 61 | ConfigLoader configLoader = new ConfigLoader(); 62 | OptionsGenerator optionsGenerator = new OptionsGenerator(); 63 | 64 | //Obtain the options from the options generator 65 | Options options = optionsGenerator.generateCli(); 66 | 67 | try { 68 | CommandLine cli = parser.parse(options, args, true); 69 | 70 | if (cli.hasOption("e")) { 71 | List paths = new ArrayList<>(); 72 | paths.addAll(Arrays.asList(cli.getOptionValues("e"))); 73 | System.out.println("[+]Received the command to start emulating " + paths.size() + " bots, loading configuration files now"); 74 | List configs = configLoader.loadConfigs(paths); 75 | 76 | if (configs.size() > 0) { 77 | System.out.println("[+]Loaded " + configs.size() + " bots"); 78 | System.out.println("[+]Starting the scheduler"); 79 | scheduler.schedule(configs); 80 | } else { 81 | System.out.println("[+]No bots were found, check if all arguments are correct and try again"); 82 | } 83 | } else if (cli.hasOption("cc")) { 84 | configCreator.cliCreation(Arrays.copyOfRange(args, 1, args.length)); 85 | } else if (cli.hasOption("cch")) { 86 | formatter.printHelp(150, "m3 -cc [required options for the requested bot family]", "", optionsGenerator.generateConfigCreationCli(), ""); 87 | } else if (cli.hasOption("cm")) { 88 | configCreator.manualCreation(); 89 | } else { 90 | formatter.printHelp(150, "m3 [mode] [options if applicable]", "Note that only one of the listed options can be executed at once!", options, ""); 91 | } 92 | } catch (ParseException ex) { 93 | formatter.printHelp(150, "m3 [mode] [options if applicable]", "Note that only one of the listed options can be executed at once!", options, "\n" + ex.getMessage()); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/emulator/OptionsGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package emulator; 18 | 19 | import org.apache.commons.cli.Option; 20 | import org.apache.commons.cli.Options; 21 | 22 | /** 23 | * This class is used to generate Options objects for the command-line 24 | * interfaces. To keep the code clearly readable, this segment is placed in a 25 | * separate class 26 | * 27 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 28 | */ 29 | public class OptionsGenerator { 30 | 31 | /** 32 | * Generates the command-line options for the main command-line interface 33 | * 34 | * @return the main command-line interface options 35 | */ 36 | public Options generateCli() { 37 | Options options = new Options(); 38 | 39 | options.addOption(Option.builder("cm").longOpt("createManual").desc("Starts the guided creation of a bot emulation project").build()); 40 | options.addOption(Option.builder("cc").argName("all required command line arguments").longOpt("createCli").hasArgs().desc("Creates a bot emulation project based on the given command line arguments").build()); 41 | options.addOption(Option.builder("cch").longOpt("command line argument creation help").desc("Lists all options for the command line creation function with a brief explanation for each entry").build()); 42 | 43 | options.addOption(Option.builder("e").argName("bot emulation path(s)").longOpt("emulate").hasArgs().desc("Loads the given bot emulation file(s) into m3 and starts the emulation of all bots via the scheduler").build()); 44 | return options; 45 | } 46 | 47 | /** 48 | * Generates the command-line options for the creation of a bot via the 49 | * command-line interface 50 | * 51 | * @return the command-line options for the creation of a bot 52 | */ 53 | public Options generateConfigCreationCli() { 54 | Options options = new Options(); 55 | 56 | options.addOption(Option.builder("bf").argName("the bot's family name").longOpt("botFamily").hasArg().desc("One of the supported families within m3").build()); 57 | options.addOption(Option.builder("bn").argName("the bot's name (local use only)").longOpt("botName").hasArg().desc("The bot's name in the logging, used locally only").build()); 58 | options.addOption(Option.builder("t").argName("the bot's tag").longOpt("tag").hasArg().desc("The bot's tag").build()); 59 | options.addOption(Option.builder("lfs").argName("the local file system path in full").longOpt("localFileSystem").hasArg().desc("The full path to the local file system, which is used by this bot to read and write files").build()); 60 | 61 | options.addOption(Option.builder("i").argName("the bot's fake imei").longOpt("imei").hasArg().desc("The bot's fake IMEI").build()); 62 | options.addOption(Option.builder("n").argName("the bot's fake number").longOpt("number").hasArg().desc("The bot's fake number").build()); 63 | options.addOption(Option.builder("op").argName("the fake phone's network operator name").longOpt("networkOperator").hasArg().desc("The name of the network operator of the fake phone").build()); 64 | options.addOption(Option.builder("lo").argName("the fake phone's locale").longOpt("locale").hasArg().desc("The fake phone's locale as a ISO-3166-1 alpha-2 country code").build()); 65 | options.addOption(Option.builder("v").argName("the fake phone's Android version").longOpt("version").hasArg().desc("The fake phone's Android version, as seen in Build.VERSION.RELEASE").build()); 66 | options.addOption(Option.builder("m").argName("the fake phone's model").longOpt("model").hasArg().desc("The model of the fake phone, as seen in Build.MODEL").build()); 67 | options.addOption(Option.builder("p").argName("the fake phone's product").longOpt("product").hasArg().desc("The product of the fake phone, as seen in Build.PRODUCT").build()); 68 | 69 | //SMS 70 | options.addOption(Option.builder("smsI").argName("recipient||text").longOpt("smsInbox").hasArgs().desc("The fake text message(s) in the inbox of the fake phone, one entry per argument, split with two pipes (being \"||\") between the recipient and the text body").build()); 71 | 72 | options.addOption(Option.builder("smsD").argName("recipient||text").longOpt("smsDraft").hasArgs().desc("The fake text message(s) in the drafts folder of the fake phone, one entry per argument, split with two pipes (being \"||\") between the recipient and the text body").build()); 73 | 74 | options.addOption(Option.builder("smsO").argName("recipient||text").longOpt("smsOutbox").hasArgs().desc("The fake text message(s) in the outbox of the fake phone, one entry per argument, split with two pipes (being \"||\") between the recipient and the text body").build()); 75 | 76 | //Contacts 77 | options.addOption(Option.builder("c").argName("name||number").longOpt("contacts").hasArgs().desc("The fake contact(s) in the fake phone, one per argument, split with two pipes (being \"||\") between the name and number of the contact").build()); 78 | 79 | //SP is skipped 80 | //Permissions 81 | options.addOption(Option.builder("perm").argName("the permission(s) the bot has one the fake phone").longOpt("permissions").hasArgs().desc("The permission(s) of the bot on the fake phone, use \"permissions_all\" to add all permissions to the bot").build()); 82 | 83 | //Installed applications 84 | options.addOption(Option.builder("apps").argName("package name").longOpt("applications").hasArgs().desc("The installed applications on the fake phone").build()); 85 | 86 | //C2 87 | options.addOption(Option.builder("c2").argName("the C2 server of the bot").longOpt("c2Server").hasArg().desc("The C2 server that the bot should connect to. Only include the IP or domain (including the protocol, excluding a trailing slash, i.e. https://127.0.0.1)").build()); 88 | 89 | //Old servers is skipped 90 | //registered is skipped 91 | //user agent 92 | options.addOption(Option.builder("ua").argName("the user agent to use").longOpt("userAgent").hasArg().desc("The user agent that should be used when making HTTP connections").build()); 93 | 94 | //rooted 95 | options.addOption(Option.builder("r").argName("if the fake phone is rooted").longOpt("rooted").hasArg().desc("True/t/yes/y if the fake phone is rooted, false/f/no/n if not").build()); 96 | //default sms manager 97 | options.addOption(Option.builder("man").argName("if the bot is the default SMS manager on the fake phone").longOpt("defaultSms").hasArg().desc("True/t/yes/y if the bot is the default SMS manager on the fake phone, false/f/no/n if not").build()); 98 | 99 | //default interval 100 | options.addOption(Option.builder("int").argName("the interval in seconds as a whole number").longOpt("interval").hasArg().desc("The interval between polling in seconds. If the C2 returns a specific polling value later on, this value is overwritten").build()); 101 | 102 | //is device admin 103 | options.addOption(Option.builder("da").argName("if the bot is device admin on the fake phone").longOpt("deviceAdmin").hasArg().desc("True/t/yes/y if the bot is device admin on the fake phone, false/f/no/n if not").build()); 104 | 105 | //is screen locked 106 | options.addOption(Option.builder("scrn").argName("if the fake phone's screen is locked").longOpt("lockedScreen").hasArg().desc("True/t/yes/y if the fake phone's screen is locked, false/f/no/n if not").build()); 107 | 108 | //Battery ercentage 109 | options.addOption(Option.builder("bp").argName("the fake phone's battery percentage").longOpt("batteryPercentage").hasArg().desc("The battery percentage of the fake phone, between 1 and 100. Going over or under the limit will result in the maximum or minimum value respectively.").build()); 110 | 111 | //active is skipped (= true) 112 | //rc4key (anubis and cerberus only) 113 | options.addOption(Option.builder("rc4").argName("the rc4 key").longOpt("rc4Key").hasArg().desc("The RC4 key that is used when communicating with the C2 server. Note that this is only used in Anubis and Cerberus").required(false).build()); 114 | //id is cerb only, but auto generated 115 | 116 | //proxy server 117 | options.addOption(Option.builder("proxyA").argName("the proxy address").longOpt("proxyAddress").hasArg().desc("The proxy address, if one wishes to use a proxy server. This argument is optional for any bot!").required(false).build()); 118 | options.addOption(Option.builder("proxyP").argName("the proxy port").longOpt("proxyPort").hasArg().desc("The proxy port, if one wishes to use a proxy server. This argument is optional for any bot!").required(false).build()); 119 | 120 | options.addOption(Option.builder("sf").argName("the folder on the C2 server").longOpt("serverFolder").hasArg().desc("The folder where the PHP files reside on the Anubis C2 folder, excluding the domain, and without any leading or trailing slashes. In this example URL: \"127.0.0.1/abc/a11.php\", the folder name is \"abc\"").required(false).build()); 121 | 122 | return options; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/scheduler/BotScheduler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package scheduler; 18 | 19 | import bot.IBot; 20 | import bot.IConfig; 21 | import config.ConfigLoader; 22 | import java.time.LocalDateTime; 23 | import java.time.temporal.ChronoUnit; 24 | import java.util.Collections; 25 | import java.util.Comparator; 26 | import java.util.List; 27 | 28 | /** 29 | * This class is used to schedule any amount of bots, based on a list of bot 30 | * configuration objects. The bots will be loaded in the given order, after 31 | * which they are sorted in chronologic order, starting with the bot which has 32 | * its next polling moment the earliest from the time when the scheduler is 33 | * executed. The list is sorted again after each bot emulation sequence. 34 | * 35 | * @author Max 'Libra' Kersten [@Libranalysis, https://maxkersten.nl] 36 | */ 37 | public class BotScheduler { 38 | 39 | /** 40 | * The provided list of bot configuration files are converted into bots, 41 | * after which they are scheduled. The bots are sorted in such a way that 42 | * the bot that is first due, is the first in the list, even if this moment 43 | * in time has already passed.
44 | *
45 | * Upon finishing the emulation of a specific bot, the list is sorted again. 46 | * This way, the bot that is first in line, is the one that needs to poll 47 | * the earliest in the future. If there is time between the moment the 48 | * sorting has finished, and the next bot, the scheduler will sleep.
49 | *
50 | * A known and unhandled edge case is a denial-of-service of sorts, where 51 | * the emulation of a specific bot is longer than the interval that is set. 52 | * As such, the same bot will get scheduled as the first to be executed and 53 | * thus (partially) blocking other bots from being emulated. Based on the 54 | * interval of bots in the wild, this is not an issue. However, if this 55 | * becomes an issue, a more rudimentary approach of simply iterating the 56 | * whole list can be used. Alternatively, one can add code to handle this 57 | * edge case in this scheduler. 58 | * 59 | * @param configs the list of configuration files for the bots that need to 60 | * be scheduled 61 | */ 62 | public void schedule(List configs) { 63 | //Initialise the config loader 64 | ConfigLoader configLoader = new ConfigLoader(); 65 | 66 | //Instantiate the list of bots, and load all bots into the list 67 | List bots = configLoader.loadBots(configs); 68 | 69 | //Start the scheduling loop 70 | while (true) { 71 | try { 72 | /** 73 | * The list can be empty for two reasons, which are given below. 74 | * 75 | * 1. No bots were loaded, as the config list was empty 76 | * 77 | * 2. All bots that were once added, have become inactive, and 78 | * have thus been removed from the list of bots. 79 | */ 80 | if (bots.isEmpty()) { 81 | System.out.println("[+]No active bots are present in the schedule"); 82 | return; 83 | } 84 | 85 | //Sort the bots in a chronological order 86 | Collections.sort(bots, new Comparator() { 87 | @Override 88 | public int compare(IBot o1, IBot o2) { 89 | return o1.getNextPollMoment().compareTo(o2.getNextPollMoment()); 90 | } 91 | }); 92 | 93 | //The earlier check already made sure that the list was not empty, meaning there is at least one entry available 94 | IBot bot = bots.get(0); 95 | 96 | //If this bot is inactive, it is removed from the list, and the next bot is loaded 97 | if (bot.isActive() == false) { 98 | bots.remove(bot); 99 | continue; 100 | } 101 | 102 | /** 103 | * The selected bot is the first one that needs to be emulated, 104 | * but that does not mean that it should be done right now. Only 105 | * if the moment in time when it should execute has passed, it 106 | * should do so. 107 | * 108 | * If it should not execute yet, it should wait until that 109 | * moment in time has just passed. This is done by sleeping for 110 | * ten seconds, before the next iteration in this loop starts, 111 | * until the bot's scheduled moment just passed. 112 | * 113 | * In the meantime, the user is kept up to date on what the 114 | * framework is doing via the standard output, where it lists 115 | * the time until the next bot's execution. 116 | * 117 | */ 118 | if (LocalDateTime.now().isAfter(bot.getNextPollMoment())) { 119 | if (bot.isRegistered() == false) { 120 | bot.register(); 121 | } else { 122 | bot.poll(); 123 | } 124 | bot.setNextPollMoment(LocalDateTime.now().plusSeconds(bot.getInterval())); 125 | 126 | bot.save(); 127 | } else { 128 | LocalDateTime now = LocalDateTime.now(); 129 | long differenceInSeconds = ChronoUnit.SECONDS.between(now, bot.getNextPollMoment()); 130 | //Calculate the amount of seconds 131 | long seconds = differenceInSeconds % 60; 132 | //Calculate the amount of minutes 133 | long minutes = (differenceInSeconds / 60) % 60; 134 | //Calculate the amount of hours 135 | long hours = (differenceInSeconds / (60 * 60)) % 24; 136 | String time = String.format("%03d:%02d:%02d", hours, minutes, seconds); 137 | 138 | System.out.println("[+]No bot has to be emulated right now, waiting for the next bot's timing in " + time + " (hhh:mm:ss)"); 139 | 140 | //Ten seconds 141 | long sleep = 10 * 1000; 142 | if (differenceInSeconds < 10) { 143 | sleep = differenceInSeconds * 1000; 144 | } 145 | //Sleep a minimum of one second, avoiding spam in the console 146 | if (sleep < 1000) { 147 | sleep = 1000; 148 | } 149 | Thread.sleep(sleep); 150 | 151 | } 152 | } catch (InterruptedException e) { 153 | System.out.println("[+]The emulator has been interrupted whilst waiting for the the next bot, as is printed above"); 154 | } 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /target/apidocs.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThisIsLibra/m3/101b9066ee6e12374d3a62e22a5ccf27054bf594/target/apidocs.zip -------------------------------------------------------------------------------- /target/m3-1.0-stable-jar-with-dependencies.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThisIsLibra/m3/101b9066ee6e12374d3a62e22a5ccf27054bf594/target/m3-1.0-stable-jar-with-dependencies.jar --------------------------------------------------------------------------------