├── 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
--------------------------------------------------------------------------------