Static Analysis of APK files
How to analyze Android applications for signs of malicious intent
Problem
Android applications have the file format .apk. Adversaries will often try to lure a user to install a malicious APK in order to compromise their Android device. Static analysis of an APK file can tell us if there are any signs of malicious intent in the file. It allows us to extract code and configuration indicators from the file.
Solution
Acquiring the file
Before an APK file can be analyzed, it must be extracted from the phone. You can extract the APK from the Android device by following the instructions in article Article #303, which includes instructions on how to use ADB (Android Debug Bridge). ADB is available for Linux, MacOs, and Windows.
Snoopdroid from Claudio Guarnieri simplifies the use of ADB, and can be used as well.
AirDroid is a free app that lets you manage your Android device using a computer’s browser. You can also use it to make a backup of apps installed on an android device, which will allow us to extract application APKs. The platform supports Windows, MacOS, Linux, or any computer with an internet browser. The link between the phone and the computer is enabled once the two devices are connected to the same network.
If the client provides a download URL for the APK, this URL should be considered malicious. Downloading the file from the given URL could be a solution, but precautions should be taken to avoid alerting the attacker and revealing your IP to them.
Static Analysis
IMPORTANT NOTE: Once the APK file is extracted, a hash should be generated and checked through our available threat sharing platforms like MISP to see if there is any previous report for it. This is the quickest way to provide an incident response. This should also be done with the download URL. The rest of this article is only used when there is no existing report for the APK file or the download URL, or to confirm an existing report result.
We will use Mobile Security Framework (MobSF) to perform a static analysis of the APK file. This tool will generate a report that includes hints about the dangerous components if they exist, with explanations, based on the threat bank that comes with the tool. Make sure that you update it frequently, and always check for updates before starting analysis.
In the next section you’ll find the report components that would help you identify if the APK shows malicious signs.
Report Structure:
Information
Displays data such as app icon, app name, size, package name etc. MD5 & SHA1 are also shown. They can be used to detect known malicious applications by entering them in public (VirusTotal) or private (CiviCERT MISP instance) threat sharing platforms.
Permissions
All apps use Permissions in order to perform tasks that are not necessarily malicious. But in this section, we will analyze the permissions that are often used for malicious purposes.
- Examples of permissions used in malicious apps:
- android.permission.ACCESS_NETWORK_STATE: Allows the app to access information about networks.
- android.permission.ACCESS_WI-FI_STATE: Allows the app to access information about wi-fi networks.
- android.permission.CALL_PHONE: Allows the app to call any number without going through Dialer.
- android.permission.CHANGE_NETWORK_STATE: Allows the app to change network connectivity state.
- android.permission.GET_ACCOUNTS: Grants the app access to the list of accounts in the account service.
- android.permission.INTERNET: Allows the app to open network sockets.
- android.permission.INSTALL_PACKAGES: Allows the app to install packages.
- android.permission.READ_CONTACTS: Allows the app to read user’s contacts data.
- android.permission.READ_LOGS: Allows the app to read low-level system log files.
- android.permission.READ_PHONE STATE: Grants the app read only access to phone state.
- android.permission.READ_SMS: Allows the app to read SMS messages.
- android.permission.RECEIVE_BOOT_COMPLETED: Allows the app to receive signals after system finishes booting.
- android.permission.RESTART_PACKAGES: Deprecated in API level 8. This API is no longer supported.
- android.permission.RECEIVE_SMS: Allows the app to record incoming SMS messages and perform processing on them.
- android.permission.SEND_SMS: Allows the app to send SMS messages.
- android.permission.RECORD_AUDIO: Allows the app to access the device’s audio input for voice recording.
- android.permission.ACCESS_FINE_LOCATION: Allows the app to access information about the device’s location.
- android.permission.CAMERA: Allows the app to open the device’s camera.
- android.permission.PROCESS_OUTGOING_CALLS: Allows the app to see the number being dialed during an outgoing call with the option to redirect the call to a different number or abort the call altogether.
- android.permission.BLUETOOTH: Allows the app to use the device’s bluetooth adapter.
Binary analysis
Use this section to identify security issues. For complex systems using third party libraries for which source code is not available, binary code analysis helps to identify issues.
- Examples of the threats could be:
- Strings pointing to system binaries: this may be a legitimate root detection mechanism or part of an escalation of privilege exploit.
- Hardcoded IPs in the binaries: these may be IP addresses for testing servers forgotten by developers or for command-and-control servers (botnets).
Android JAVA API
API stands for Application Programming Interface. It can be defined as a set of protocols, procedures, and tools that allow interaction between two applications. Simply put, the moment you add an endpoint to a URL and send a request to a server, this is what counts as making an API call. For example, when you login to any app or ask a question via a browser, you are actually making an API call. Unfortunately APIs can be used for hacking purposes to gain access to sensitive user information like names, locations and other personal data.
In this section we’re going to review Android API calls and look for malicious ones.
Malicious API calls could be:
- SMS: the API calls below will allow the app the send and receive SMS.
- sendTextMessage()
- sendMultipartMessage()
- sendBroadcast()
- sendDataMessage()
- Telephony.SMS-Received
- content:sms
- Privacy: the API calls below will allow the app to obtain the device’s phone number, IMEI, SIM card serial number, network operator, device ID, and Outgoing calls records.
- getSimSerialNumber()
- getCallState()
- getDeviceId()
- getLine1number()
- getSubscriberId()
- getSimSerialNumber()
- getImei()
- getSimOperator()
- getDeviceId
- getLineNumber()
- getNetworkOperator()
- newOutgoingCalls()
- Network: the API calls below will allow the app to gather network information such as IP address, Mac address, SSID, HTTP headers.
- httpclient.execute()
- getoutputstream()
- getInputStream()
- getNetworkInfo()
- httpUrlConnectionConn()
- SendRequestMethod()
- setDataAndTypes()
- Location: the API calls below will allow the app the gather information about the device’s location.
- getLongitude()
- getLatitude()
- getCellLocation()
- requestLocationUpdate()
- getFromLocation()
- getLastLocationKnown()
- Application: the API calls below will allow the app to install updates from new packages. The source of these packages should also be checked.
- GetInstallPackages()
- InstallPackages()
- Component: the API calls below will allow the app to perform long-running operations in the background without providing a user interface. Once started, a service might continue running for some time, even after the user switches to another application.
- startService()
- setComponent()
- WIFI: the API calls below will allow the app to enable the WIFI adapter and get information about the WIFI state.
- getWifiState()
- getEnabled()
- getWIFIEnables()
- File: the API calls below will allow the app to load assets, either for a file stored in the installation package or from a URL.
- URL(), getAssets()
- openfileoutput
- Browser: bookmarks_URL
- Function calls: the API calls below will allow the app to interface with the environment in which the application is running.
- Runtime.exec()
- Obfuscation: the API calls below will allow the app to execute code not installed as part of an application. Cryptographic ciphers for encryption and decryption can be added for obfuscation.
- DexClassLoader
- Cipher.getInstance()
Security analysis
-
Manifest analysis: finds vulnerability inside one of the components in the AndroidManifest.xml file. Related mostly to the protection of services and receivers implemented by this app.
-
Code analysis: identifies potential vulnerabilities, determines their severity, and shows the files in which this type of vulnerability was found.
-
CVSS (Common Vulnerability Scoring System): Vulnerability is assigned a CVSS base score between 0.0 & 10.0 with the following values displayed: No risk, Low risk, Medium risk, High risk, Critical risk score.
-
CWE (Common Weakness Enumeration): a list of software architecture, design, or code weaknesses. MobSF will display a reference that can be shared in CWE databases.
-
File analysis: files embedded in the APK extracted for more analysis.
-
Domain Malware check: check the identified IPs and Domains against threats banks and reflect their reputation to you.
-
URL: display a list of URLs, IP addresses, and the files in which they are stored or called. Analyzes where the Android app sends the data & where it stores the information.
-
Emails: displays all written email addresses in the code.