WatchGuard recently released its Internet Security Report (ISR) for Q4 2018. In addition to the many interesting details of malware attacks, IPS hits, and top security incidents, there is also a Threat Research section that covers the Exobot malware campaign. You can listen to The 443 Podcast’s overview of the report if that’s your groove. This post is not a regurgitation of that, rather how the team and I went about analyzing the procured source code.
To ensure you’re familiar with what Exobot is, I will repeat the overview of it, but then follow up with how I went about debugging the server while trying to set it up. The ISR covers more of the functionality of the malware package; be sure to read it afterwards if you haven’t already to get more details about the Android application counterpart.
This is the story about how the WatchGuard Threat Lab team went about analyzing Exobot’s source code and functionality.
Overview of Exobot
Back in 2016, Exobot’s author posted version 2’s source code for sale online on various hacker forums and the dark web. Exobot is a sophisticated malicious botnet package for Android devices. The variant we analyzed targets specific countries by enforcing a list of predesignated countries it avoids. Exobot is also a banking trojan, meaning it primarily targets banking apps and other financial services using an overlay attack. An overlay attack detects apps it knows and “overlays” an invisible interface over the app’s real user interface (UI) in order to intercept user inputs like usernames and passwords. Exobot even abuses Android’s DevicePolicyManager API, a set of administrative functions that give system-level access, to perform nefarious activities like disabling antivirus programs.
For example, if a victim downloads a third-party application from an unofficial Android repository, they may also inadvertently get Exobot as well. Then, when that user opens their financial institution’s mobile application (or any other financial app the malware knows about), Exobot detects, intercepts, and overlays a transparent window over the legitimate app. When the victim enters their credentials into the login form, Exobot’s overlay captures them and sends them back to the attacker.
Before Exobot’s author posted it for sale, they offered it as a rented service where customers could purchase time in segments of weeks and months. Now, however, anyone with technical know-how can download the leaked source code, make modifications to it, and launch a fresh malware campaign.
The Shell Structure
Upon decrypting the password and extracting the content, there are three main directories: exo, loader, and socks.
The exo directory stores the entire ecosystem of the malware, including malicious versions of legitimate application frontends and also user and admin backend panels. Nested directories within exo include:
- backend_server – houses the command and control (C2) infrastructure; a bot-interaction panel for customers, an admin panel, as well as a storehouse for compiled APKs
- frontend_server – used to hide the backend behind a separate frontend Nginx proxy
- builder_server – which can be used to manage customer accounts, bot templates, build APKs – it’s the powerhouse
Figure 1 depicts the README.txt file within this directory describing the contents of each sub-directory.
Next, the loader directory houses the following sub-directories:
- bot – malicious Android application’s source code
- panel – which contains backend web server files and scripts for setting up the bot management database.
The panel structure appears to be incomplete. There is a file to create the bot database used throughout other scripts in that same directory but the file itself is empty.
Finally, the socks directory, which contains a separate module that allows attackers to proxy connections through infected devices using the SOCKS protocol. This directory contains the following sub-directories:
- android_service – the source code for the Android SOCKS service that can be embedded into the bot clients, allowing attackers to divert their network traffic through infected Android devices
- linux_server – this houses an example of a built server that is ready to deploy
- php_panel_example – holds all the files from the older bot panel versions
To give you a better idea of just how many files and directories there are in the procured source code sample, refer to the stats in Table 1. It’s worth mentioning that there are duplicate directories nested within multiple locations.
|Content Type||Number of Items|
Table 1: Number of directories and file within Exobot’s source code
I’m going to breakdown this post into different sections and dive into the details of what makes Exobot what it is. Further, this report will focus on the exo directory’s backend_server directory and briefly the frontend_server directory. There will be a virtual tour of the admin panel backend as well as the customer panel. Refer to the Q4 ISR linked in the opening paragraph for insight on the functionality of the bot client itself.
Starting with the backend_server directory, which is pretty much the meat and bones of the Exobot source code. Fortunately, there is a SETUP.txt file (akin to a README file) that provides guidance on setting up the backend server; however, it is not the clearest in its description of the setup process. This file can be broken down into four main chunks:
- Server setup – details what server resources should be allocated to the backend server, as well as what software packages are to be installed
- Structure – describes other files and nested directories within the root directory
- Setup – details the process to take to get the server up and running
- Admin panel usage – informs its reader what to do when you get the server up and running, and a description of the layout of the web app
Refer to Figure 2 for a visual representation of the content of backend_server. Other top-level directories are: apache_ip_block, lists of IP addresses to deny access to the backend server; sites-enabled, configuration files of web pages to be served; SQL, this stores the content for creating the databases; and www, which stands for world wide web and houses the content being served via the web server.
I’ll cover the content within as I continue through this blog, but the names should more or less give you a fair understanding of what they entail. Loose files include “backend_backup.sh”, “customers.passwd”, “INSTALL.sh”, “panel.passwd”, “remove_logs.sh”, and “SETUP.txt”.
Working Through SETUP.txt
This section will cover the SETUP.txt directions broken into four portions as mentioned above.
One of the three listed steps is to move all content to a newly created directory named “/var/data”; check.
Next, install the required software – see Figure 3.
Installing Packages and Enabling Apache2 Modules
Thinking back to current directory’s contents, there is a file named INSTALL.sh. Logically this seems to be the script to get the server up and running based on its name. When opening and reviewing the file, there is an impressively written installation script that’s broken down, making it easier to understand what it does – refer to Figure 4. At the top is the software requiring installation, followed by three Apache modules needing to be enabled; rewrite (allows manipulation of URLs), ssl (secure web socket communications), rpaf (Reverse Proxy Add Forward).
Having first tried to automate the installation by adding an execute attribute to the script then running it, errors arose that required troubleshooting. This was due to the fact that the source code was released years ago and some required packages have been updated and/or possibly deprecated since – this was true for needing php5 at least.
PHP is a fairly common scripting language used in web development. Fortunately, this was a simple fix by dropping the 5 and running apt-get -y install php which yielded the installation of PHP 7.0. Finally, enabling the listed apache modules, we’ve completed the server setup portion of the INSTALL.sh document!
PHP and Apache2 Configuration Changes
Continuing with the installation script, there were a few PHP 5-specific configuration file modifications that were adjusted to correlate with PHP 7’s directory structure; one raised the limits of certain content upload submissions and the other enabled the displaying of PHP errors. Before doing this, and moving forward, I created backups of files-to-be-modified. Following that were a few Apache changes, including adjusting the web ports the server is listening to and changing the directory housing the site-specific configuration files (the web servers root directory); bear in mind the sites-enabled directory in the main directory aforementioned. Lastly, use a good old apache2ctl restart command to restart the Apache service and incorporate the changes and…uh, oh. Refer to Figure 6 to see the presented error message.
The displayed image shows an “SSLv3 not support by this version of OpenSSL” error, so Apache’s service was unable to restart. Opening each of the two listed configuration files nested within the sites-enabled directory (../bot.conf and ../cp.conf) individually, there is a section displaying supported SSLProtocol (refer to Figure 7).
Based on the error and the supported SSL protocols, simply removing “+SSLv3” from both files yielded a successful apache2ctl restart command.
Creating a Log Directory and Adding Some Anonymity
Next up was creating a logs/ directory within /var/data/, to store log files, and making adjustments for user permissions to this directory for the www-data user – the account associated with Apache services, per its configuration file. There are a few other instructions pertaining to anonymity; nullifying login tracking and denying SSH keys from being altered.
Last but most certainly not least, I needed to setup some credentials for accessing the control panel as an admin, and also for optionally allowing customer panel access.
Step 2: check!
The last step suggests either encrypting the contents stored within /var/data/ or, alternatively, using disk encryption if supported by the hard drive within the system. Considering that setup is in a controlled environment, we’re going to skip this.
Step 3: check!
The details this section provided within SETUP.txt describe the contents within the root directory and what each file or directory is for. This was more or less covered above, when displaying Figure 2. However, I do want to focus more on the www directory.
This directory houses additional sub-directories;
- apks – (Android Packages) stores APK files for customers;
- base/bot/ – which houses the scripts used to render customer panels based on their specific configuration details (auto-generated within their personal directory);
- bot – is the default directory Apache directs bot client requests too, as configured in the bot.conf configuration file, but this directory is symlinked to another directory within www named clients;
- clients – where all customer-specific configurations are stored and the actual template structure for new customers are stored;
- lastly is cp – which is the storehouse for the backend control panel itself.
Setup (And a Quick Glimpse at the Backend Control Panel):
This section is intertwined with the INSTALL.sh script covered above but expands on other processes to be set up, primarily the need of requiring authenticated access to certain resources. This is done via files known as .htaccess. These files allow Apache web servers to do many things, of which one is to ensure authentication requirements. There needs to be a unique password file for customers (customer.passwd) as well as backend admin panel (panel.passwd) access.
Another step is to go into the SQL folder and carry out its README.txt file, but we’re skipping this for now as it’ll be covered in a separate section. Then there are two changes that need to be edited in the respective configuration file for an already-existing TestUser account. One of the two changes is to modify information for the respective user’s database, which will be covered in another section with the SQL directory, and the other to establish a directory path to the /base/bot/ directory covered above.
There is an explicit note to not delete anything within the data structure, doing so may prevent full functionality of the backend panel and the customer panel accounts. Further, there are instructions on how to enable the C++ standard library to allow for Android OS development, libc++.so. Lastly, we need to direct Apache2 to our /var/data/sites-enabled/ directory where our own virtual hosts files are stored.
Still needing to get much work done, I at least got the display of the control panel up and working (Figure 8).
Admin Panel Usage:
Having skipped over a few bits above – the SQL details at least – the final section of SETUP.txt described in Figure 8 depicts the different menu options; Add customer, Customers, Backups, etc. The names of the menu options should be clear, except for Injects list– which displays all injects with screenshots and edit forms. We’ll have to get back to this once we get the database up and running.
Setting up the Database and Configuring Authentication Requirements
Applications wouldn’t be any good without saved, persistent data. The SQL directory that was skipped in the above section deserved a section for itself. Within this directory is a README.txt file, and three .sql execution files; blank_bot, general, and is_online. In this section we will cover the created databases per these execution scripts.
The malware infrastructure supports multi-tenancy, meaning different user accounts (customers) can manage their own network of bots. This file contains the templates for all of the tables that the server must create when adding a new user. You can see the tables it creates in Figure 9.
First off, bots is among the most interesting as it stores a lot of information from infected Android phones. Mined information includes the phone’s IMEI number, its IP address, its country and whether the malware obtained admin API access, as well as a list of about 20 other things.
Next, the bot_cards table stores personal information about the phone’s user, such as their name, address, birthday, and a dozen other personally identifying attributes.
Finally, the bot_tasks table is where the command server stores pending commands to send to infected phones.
This is a short file that holds a SQL function that checks if a bot is online by checking the timestamp from when the bot last checked in.
This file generates tables that have to do with the bot’s infectious and evasive capabilities. It creates tables that house the apps the malware can target, and which antivirus (AV) and security programs to block, among other things.
You can see the database tables it creates in Figure 10.
An interesting table from this list is minimize_apps_list, which lists many antivirus (AV) products that the bot app keeps minimized. Some example AV products include AVG, Avast, and BitDefender, as well as a few others we haven’t heard of; see the Q4 2018 ISR’s Appendix A for a full listing.
Another table is injects. It stores an extensive list of the banking, shopping, and social media sites the botnet has overlays for. It contains almost 150 items; see the ISR’s Appendix B for a full listing. The web server uses this list to display Exobot’s potential targets to customers.
Update Admin User
Lastly, there is an auto-generated salt value used in conjunction with the password set when creating a new user. A salt value can be a stringed value that is appended to a user’s input for their desired password. The two together are ran through a hashing algorithm (md5) and stored for future recall and verification. This method prevents plain text passwords from being stored, first off, and the unique salt string also adds additional characters to further prevent a possible duplication of a hashed value.
To be clear, hashed values should return an expected unique hashed value. No two hashes should be the same, but if two users use the same password, a different salt value should clear the duplication of the same hash for the same password.
During the troubleshooting process, there were a few locations that designated a root user for accessing the database. This is the superuser of Linux-based systems. Unfortunately, the ability to directly access MySQL databases as this user is no longer supported by PHP.
There is also PHP Data Objects (PDO), an interface that allows PHP to interact with databases. This is used in conjunction with MySQLi functions, which replaces the now deprecated MySQL. After updating the information needed and correcting database access by the preset user (TestUser / panel2), we get what’s depicted in Figure 11.
Final Touches and a Picture Gallery
As you may have caught onto so far, the source code wasn’t a simple ‘run and install’ scenario. In fact, going through what we did thus far exhibited many errors that needed rectification. From Figure 11, you can see a few errors already (the /usr/lib/…error was a skipped step) but even if you click on any other menu option, there are error messages that need attention.
Most errors were straightforward, as the logs were clear in the issues. Other errors, though syntactically correct, were not semantically sound. That is, though the content was still being rendered, it wasn’t displaying the content as it should have. This required a manual review of the many different components that made up the admin backend panel. After doing all this, you can really appreciate the code for what it is.
Figure 12 shows the Apache web server prompting for user authentication prior to allowing backend admin access. This is the web server itself, and not the web application requesting authentication.
Figure 13 is the landing page, which brings the admin to the Customers web page. This allows admins to have an overview of the customers leasing space on the platform.
Figure 14 shows a sample list of known applications that Exobot contains and can perform overlay attacks on. This is by no means an exhaustive listing of preloaded application.
Customer Admin Panel
After configuring the backend details, let’s shift focus to the customer login portal. There are three main customer-oriented views: one is bot access, which is how the mobile application communications with the backend panel; another is stats access, which provides statistics of usage and related details; and the last is panel access, which is what allows customers to see the mined information their malicious application has gathered.
Figure 15 shows the customer authentication screen presented by the Apache web server. Figure 16 shows the web application prompting for user authentication.
You may have noticed the use of two different usernames when comparing the above-two Figures. This is because the Apache authentication is related to the specific user (the authentication is checked against the customer.passwd file); the customer panel’s username is hardcoded to “admin” specifically. Also, the password is different for Apache and the customer login, as well as the specific database that’s created for the user account – the latter isn’t made known to the customer. It’s only for Apache access, as well as panel access.
There are many menu options that are self-explanatory once a customer’s landing page renders per Figure 17. We’ll explore a few further down.
Figure 18 expands on the My Injects menu option and Figure 19 on the Extras menu options. Depending on what region a customer wants to target, there are regionally distinct applications for various countries; Turkey, Romania, as well as as social networks and messaging apps, and even some custom apps. Based on this, as well as the extensive list of blocked IPs, it is clear that this is a targeted malware campaign. Depending on the region of attack, there are a number of specific applications for that region.
Figure 20 shows the “Inject packs” section that displays all available country-specific packages.
Brief Look into frontend_server
This server didn’t have much to it. In fact, there was only a SETUP.txt file, setup_client_vps.sh script, and a self-contained backend_server duplicate.
Starting with the SETUP.txt file, it simply consists of the resources to allocate to this server, entering the true backend IP address that the backend panel is accessible on, and then to run the associated installation script. As for the installation script itself, rather the setup_client_vps.sh script, the only required packages are nginx-full and openssl. This is followed by creating an SSL certificate, then overwriting the default Nginx configuration in favor of an ssl configuration file. This file is where you enter the true IP address of the backend server; there are also a few header definitions. The last section of the script orients around anonymity and turning off Nginx access and error logs.
That’s it! The frontend_server was rather simple to configure. Based on the context and ecosystem of the source code, it seems as though you are able to create specific frontend access points for different customers. This would prevent multiple users from using the same frontend, as well as masking the true location of the backend server. Also, should a customer who rented time on this MaaS (Malware-as-a-Service) have their lease expire, it’d be simple to just delete the server and not have to worry about it affecting other users.
With security defenses becoming more sophisticated to keep up with the offense, the learning curve grows with it. This paves the way for MaaS offerings by malicious threat actors. As in with the case of Exobot, more technically savvy actors are able to program the ecosystem; the backend servers, communication methods between the backend server and the infected devices, and whatever else may require that skillset. They are then able to provide a platform for those less technically savvy.
Thus, the need to be savvy at all is more or less removed from the equation. The only thing an aspiring and malicious proliferator would need to focus on is spreading malware. Social engineering can come into play, or simply blasting spam to anyone and everyone with malicious attachments or links.
MaaS is not at all uncommon. In fact, in my more recent excursions on the dark web, I came across some updated services akin to Exobot. For X number of Bitcoins, you can rent space on the platform for Y amount of time. I wasn’t able to find any released source code samples, but they may surface with time.