Android software Security Development Practices (next)

Source: Internet
Author: User
Tags root access

Android Development is one of the hottest topics in the world, but few people discuss security issues in this area. This series will be divided into two phases to explore common security pitfalls and solutions in Android development. The first phase will take you on an Android software security development Practice journey from three perspectives: data storage, network communications, cryptography, and authentication policies.

Over the past two years, researchers have found widespread security flaws or security vulnerabilities in popular software on Android. There may be many reasons for the vulnerability to occur, such as the following.

    • Compared to all centrally managed iOS, Android offers an open environment that is flexible enough to meet a variety of customization needs while also losing some of its security.

    • Development teams typically focus on product design, functional implementation, user experience, and system efficiency, with little consideration for security issues.

    • Android provides a more sophisticated security mechanism that developers need to understand and understand about common attack ideas and attack methods to effectively protect the software.

    • On the one hand, there are few large-scale targeted attacks on specific mobile software security vulnerabilities, and many people do not take it seriously until a real attack occurs. On the other hand, it is not too difficult to exploit these vulnerabilities, and many attack methods and tools are ripe. In the event of such an attack, the user's personal privacy data may be compromised, the account information may be stolen and, if combined with attacks such as phishing, may even incur economic losses. The product development team may thus face a crisis of trust and legal risk.

In some of my previous security evaluations, I have seen that many development teams have a very high level of security development, but also found that there are a variety of defects in the software of well-known enterprises. In this article, we will introduce you to the more common security flaws or security vulnerabilities in Android software, analyze the causes of the problems, introduce possible attack methods, and give suggestions to solve the problem. I hope we can give some attention to this kind of problem.

Data storage

Android software can be used by the storage area divided into external (SD card) and internal (NAND flash) two kinds. In addition to the difference in size and location, there is a big difference between the two in security permissions. Externally stored files do not have read and write permissions, and all applications are free to create, read, modify, and delete any files located in external storage, and only need to declare read_external_storage and Read_external_storage permissions. Internal storage allocates private areas for each software and has Linux-based file permission controls, where each file has a user ID that is set up by Android for that software. Typically, other software does not have permission to read and write these files.

Some of the issues that may arise with data storage include the following.

Keep private data clear in the external storage

For example, chat software or social software stores chat logs, friend information, social information, etc. on an SD card, and backup software backs up records, text messages, etc. to an SD card. If the data is stored directly in plaintext (including text format, XML format, sqlite database format, etc.), then the software written by the attacker can read it and return it to the specified server, resulting in a disclosure of privacy information.

It is a good practice to encrypt the data, which is stored in the internal storage, managed by the system, or entered by the user.

Save system data plaintext in external storage

For example, backup software and system-assisted software may save the user's installed additional software data to an SD card for recovery after a flash or upgrade, or to cache some system data on an SD card for subsequent use. Similarly, if the data is stored in plaintext, the malware can read them and may be used to expand further attacks.

Save data that is dependent on the software runtime in an external storage

If the software stores the configuration file on an SD card and then reads the profiles during run time, and depending on the data in it, it can also cause problems. Software written by an attacker can modify these configuration files to control the operation of these software. For example, if the list of servers used for login is stored in an SD card and modified, the login connection is sent to the server specified by the attacker, which can lead to account leaks or session hijacking (man-in-the-middle attacks).

A more secure method for this configuration file is to save to internal storage, and if it must be stored to an SD card, it should be judged whether it has been tampered with before each use, for example, compared to a pre-saved file hash value.

Save Software installation package or binary code in external storage

Many software now recommend users to download and install other software, users click on the Internet will download another software apk file, save to the SD card and then install.

There are also some software options to dynamically load and execute binary code in order to implement feature extensions. For example, download the Dex file or jar file that contains the extension, save it to an SD card, and then, when the software is running, use the The Dalvik.system.DexClassLoader class or Java.lang.ClassLoader class loads the files and then executes the code in the Java reflection.

If the software does not verify the integrity of the files on the SD card before it is installed or loaded, it is possible that a security issue may occur if it is possible to tamper with or forge the file.

Here, an attacker could use a method called "re-packaging". This technique is already used by a large number of Android malicious code. The basic principle of repackaging is to disassemble the APK file to get the Smali syntax representation of the Dalvik instruction, and then add, modify, delete, and so on, and make appropriate changes to the manifest file; Finally, the instructions are reassembled and packaged into a new APK file, signed again, Can be installed on other phones. By repackaging, attackers can add malicious code, alter the software's data or instructions, and the software's original functionality and interface are largely unaffected and difficult for users to perceive.

If an attacker re-packs the APK file to be installed by the software or the Dex, jar file to be loaded, or modifies its original code, then on the SD card, replace the original file with it, or copy it to the path to be executed or loaded, when the software does not verify the validity of these files, The attacker's code will be run. There are many possible attacks, such as sending a debit message directly, or emailing the user's account password to the specified server, or ejecting the phishing interface.

Therefore, the software should verify the integrity of any files that reside on the SD card before installing or loading them, judging whether they are consistent with the hashes that are stored in the internal store (or downloaded from the server).

Global writable Internal files

If a developer uses the Openfileoutput (String name,int mode) method to create an internal file, set the second parameter to context.mode_world_readable or Context.mode_world_ Writeable, the file becomes globally readable or globally writable.

Developers may be trying to share data between different software, but the problem with this approach is that there is no control over which software can read and write, so malicious software written by an attacker also has this privilege.

If you want to share data across applications, a better approach is to implement a content provider component that provides read and write interfaces to the data, and sets a custom permission for read and write operations.

Internal sensitive files are read and written by the root authority software

If the attacker's software is rooted, you can naturally read and write the internal files of other software. This situation is not uncommon.

    • A large number of third-party custom ROMs provide a root authority management tool that can trick a user into giving it root privileges if the attacker constructs software artifacts that create powerful tools.

    • Even with the official system installed on the phone, domestic users are mostly happy to unlock, brush recovery and swipe into the root management tool.

    • In Android 2.2 and 2.3, there are some vulnerabilities that can be used to get root privileges, and the exploitation of this vulnerability does not require user confirmation.

Therefore, we cannot assume that other software cannot obtain root privileges. Even if there is internal data, there is still the possibility of being read or modified.

As mentioned earlier, important, sensitive, and private data should use internal storage, and now it is still possible to read the data after the root has been encountered. My view on this issue is that if an attacker is desperate to gain root authority (at the risk of being perceived by the user or discovered by the security software), then theoretically he has complete control of the system and can directly obtain contact information, SMS records, etc. At this point, it is more likely that attackers are interested in exploiting other important data that is managed by the software, such as account passwords, session credentials, account data, and so on. For example, early Google Wallets store the user's credit card data in plaintext, and after the attacker obtains the data, it can be disguised as a cardholder for further attacks to gain access to the account. This data is "other important data managed by software".

There is no universal solution to this problem. Developers may need to find a solution based on the actual situation and make the right choice between usability and security.

Network communication

Android software typically communicates with the server using a WiFi network. Wi-Fi is not always trustworthy. For example, an open network or a weak encrypted network, the user can listen to network traffic, the attacker can set their own wifi phishing. In addition, you can also listen for network data in the Android system after root access.

Transmit sensitive data in plaintext without encryption

The most dangerous thing is to log in to your account or exchange data directly using the HTTP protocol. For example, an attacker would configure a DNS server on his own phishing network to resolve the server domain name to which the software is connecting to another attacker's server, which could either obtain user login information or act as an intermediary between the client and the original server to forward both data.

In the early days, login sessions for Android clients from some of the famous social networking sites abroad were not encrypted. Then came the Hack tool Faceniff, specifically sniffing these sessions and hijacking them (it even supports attacks on WEP, WPA, WPA2 encrypted WiFi networks!). )。 This is the only case I know of publicly attacking a mobile software vulnerability.

The solution to this type of problem is obvious-the use of SSL/TLS-based HTTPS for sensitive data transmission.

SSL communication does not check certificate validity

In SSL/TLS communication, the client determines whether the server is trustworthy through a digital certificate and uses the public key in the certificate to encrypt the communication with the server.

However, there are developers who do not check the validity of the server certificate in the code, or choose to accept all certificates. For example, developers can implement a X509trustmanager interface themselves, the checkservertrusted () method is implemented as null, that is, do not check whether the server is trustworthy, or in the instance of Sslsocketfactory, through the Sethostnameverifier (Sslsocketfactory.allow_all_hostname_verifier), accept all certificates. The possible reason for these two choices is that, with the use of their own generated certificates, the client discovers that the certificate cannot form a chain of trust with the system trusted root CA, and an exception such as certificateexception occurs.

The problem that this approach can cause is a man-in-the-middle attack.

In a phishing WiFi network, similarly, an attacker could set up a DNS server to enable clients to communicate with a specified server. The attacker deploys another certificate on the server and the client receives the certificate during the session setup phase. If the client ignores the exception to this certificate, or accepts the certificate, it will successfully establish the session and begin encrypting communication. However, the attacker has a private key, so it can decrypt the plaintext of the data sent by the client. An attacker can also impersonate a client, contact a real server, and act as a middleman for listening.

One way to solve the problem is to request a certificate from a trusted CA. However, this approach is not recommended in mobile software development. In addition to the time cost and cost of applying for a certificate, this verification only determines whether the certificate is trusted by the CA, and does not verify that the server itself is trustworthy. For example, an attacker could steal another trusted certificate, or steal a CA private key to issue a false certificate for itself, an attack that has occurred several times in the past two years.

In fact, most mobile software only communicates with a fixed server, so it is possible to verify the specific certificate directly in the code, which is called "Certificate Lock" (certificate pinning). There are two ways to implement certificate locking: One is to implement the X509trustmanager interface mentioned earlier, and the other is to use KeyStore. Refer to the overview of the Httpsurlconnection class in the Android development documentation for details.

Register your account with SMS or receive a password

There are also software using SMS to communicate, such as automatically send text messages to register, receive the initial password by SMS, receive the user reset password by SMS.

SMS is not a secure means of communication. As long as the malware affirms send_sms, receive_sms and read_sms These rights, it is possible to send arbitrary text messages to any number via the system-provided API, receive text messages sent from a given number, read their contents, and even intercept text messages. These methods have been widely used in Android malicious code, and even 2011 years have appeared to intercept and return text messages in the net Silver Login Verification Code (Mtans) of the theft Trojan Zitmo.

Therefore, this method of registering or receiving passwords via SMS can cause attacks such as fake registration, malicious password reset, password stealing, and so on. In addition, this account associated with the mobile phone number may also generate value-added services, the risk is greater. The better way to achieve this is to go to the Internet.

Password and authentication policies

PlainText store and encode stored passwords

Many software have the "Remember password" function. If the developer literally stores the password locally, it can cause a leak.

In addition, some software does not directly save the password, but with Base64, fixed byte or string xor, Protobuf and other methods to encode the password, and then stored locally. These encodings also do not increase the security of the password. With tools such as Smali, Dex2jar, Jd-gui, IDA Pro, attackers can disassemble and decompile the Android software. This allows an attacker to understand how the software encodes and encodes the password.

It is a good practice to use a protocol that is based on credentials rather than passwords to satisfy the need for persistent access to this resource, such as OAuth.

Weak or fixed password for external service

Another concern has been that some software provides network services out of the way, without using passwords or using fixed passwords. For example, system-assisted software often opens the FTP service under WiFi. Some software does not use passwords or fixed passwords for this FTP service. Under an open or phishing WiFi network, attackers can also scan to the service and access it directly.

There is also the problem of weak passwords. For example, the local access password for an early Google Wallet is a 4-digit number, and the SHA256 value of the password is stored in the internal storage. There are only 10000 cases of 4 digits, so the attack software can get the password in a short period of time even if it is a direct brute force on the phone.

Use IMEI or IMSI as unique authentication credentials

IMEI, IMSI is a unique number used to identify mobile devices, mobile cards. The use of IMSI or IMEI as a unique credential for user authentication can lead to an attack by a fake user.

First, the application wants to get the IMEI of the handset, the IMSI of the mobile card does not need special permission. In fact, many third-party ad libraries callback them for user statistics. Secondly, after obtaining the IMEI or IMSI, the attacker has many methods to cause the user to communicate with the server. For example, the original software is repackaged to get the IMEI, IMSI code always return the specified value, or modify the Android code, so that the relevant API always return the specified value, compiled as ROM run in the emulator, and can even analyze the client-server communication protocol, directly simulate the client's network behavior.

Therefore, if the IMEI or IMSI is used as the only credential for authentication, the attacker may obtain user accounts and data from the server.

We discuss security issues and solutions such as data storage, network communications, cryptography, and authentication policies, and will continue to practice the security development of Android software from inter-component communication, data validation, and preservation protection.

Inter-component communication

The security of inter-component communication is unique to Android, and is one of the most common problems in the current software.

Let's review the communication mechanism between components. Android has four types of components: activity, service, broadcast receiver, and content provider. Among the same software or between different software, the first three kinds of components use intent to call each other, use Contentresolver object to access content provider, together realize the function of software. With intent, you can call explicitly or implicitly:

    • Explicit (Explicit): The caller knows who to call, specifying the specific callee through the component name;

    • Implicit (implicit): The caller does not know who to call, only knows the action performed, and the system chooses the component to process the request.

As shown in the following code:

Whether explicit or implicit, if you want to call across applications, you also need to expose the components that are called externally. By default, service, broadcast receiver, and content provider are exposed, stating that Intent-filter's actvity is also exposed.

In an abstract way, component A calls component B to complete a function for B, which can send some data to component B, or it can get a return result after B execution. In this model, problems arise between A and B and are not necessarily mutually credible.

If B is exposed, any software can invoke it, including software written by the attacker. An attacker might but not always succeed:

    • Direct invocation of exposed B to obtain its execution result;

    • Constructs a specific data and is used to invoke the exposed B, thereby attempting to influence the execution of B;

    • Invokes the exposed B and gets the result that it returns after execution.

If a is implicitly called, any software can implement its action to respond to the call. An attacker may (but not always succeed):

    • Constructs a forged component C, responds to the intent of a, to read the data of a to be sent to B;

    • Constructs a forged component C, responds to A's intent, pops up a false user interface for further attacks (such as fishing);

    • Constructs a forged component C, responds to the intent of a, and returns a fake execution result.

That might be more abstract. We'll discuss each of these two situations separately.

Problem with component exposure

See an example. In a third-party in-depth custom ROM, software called cit.apk is preinstalled for hardware testing of mobile phones. Its androidmanifest.xml is localized as follows:

As you can see, it declares a name of. Citbroadcastreceiver receiver, responds with an action named Android.provider.Telephony.SECRET_CODE, and specifies the URI format.

Then look at this receiver code snippet (the following code is I decompile, not necessarily with the software source exactly):

As you can see, when this receiver is called and the host field in the provided URI is 284, the local Bugreport tool is called with root permission and the result is output to the file specified in M_logfilename.

Receiver is exposed by default, so this receiver can be called by other software, with the following code:

When these four lines of code are executed, the Citbroadcast-receiver code is triggered. From the context, the output file M_logfilename is located in the SD card, any software can be read and write freely. As a result, an attacker can obtain bugreport output, which contains a large amount of system data and user data.

Note that in this example, the attacker's software does not require any special permissions, especially if root permissions are not required. This is called permission re-delegation (permission re-delegation) because the component exposes an attack that gets additional permissions.

How do I avoid security issues due to component exposure? Some components must be exposed, such as entry activity, or do not provide services externally or collaborate across software, but there are components that are not necessarily exposed. Next we'll discuss them separately.

Components that do not need to be exposed

Again, by default, service, broadcast receiver, and content provider are exposed, stating that Intent-filter's actvity is also exposed. If they are only called by code in the same software, they should be set to not be exposed. Easy to do-Add the attribute android:exported= "false" to this component in Androidmanifest.xml.

Components that need to be exposed

If the component needs to be exposed externally, the call to it should be restricted through custom permissions.

First, you customize a permission in the android-manifest.xml of the software that implements the called component:

Next, add the permission limit for the called component, which is to add the Android:permission property to the component in Androidmanifest.xml:

Another approach is to use context.checkcallingpermission () in the implementation code of the component to check whether the caller has this permission.

Finally, to invoke this exposed component, the caller's software should declare that the permission is used, i.e. add the appropriate use-permission declaration to the Androidmanifest.xml.

Further, there are two scenarios in which the requirements for this component exposure can be divided.

    • If this component is intended to be used only for other software that it develops, and does not want to be exposed to third-party software, the ProtectionLevel field should select signature when defining permissions. This setting requires that the permission consumer (that is, the caller) and the permission definition (that is, the callee) must be signed by the same certificate, so that the third party cannot use the permission and cannot invoke the component.

    • If this component is to be exposed to a third party, Protection-level should use normal or dangerous. At this point, any software can use this permission, and the user will be notified only at the time of installation. Considering that the user generally ignores the permission prompt, the custom permission actually loses the protection effect, we still have to scrutinize the code of the component, avoid the problem such as ability leak or authority re-delegation.

In addition, for content provider, you can set different permissions for reading data and writing data in finer granularity, and the corresponding manifest tags are android:readpermission and android:writepermission, respectively.

An implicit invocation of the problem

The main problem with implicit invocation is that the data being hijacked, or intent carried, is read.

In order to hijack a call, an attacker could implement a malicious component that declares the same intent-filter. In the case that multiple components can respond to the same intent, if the activity is called, the system will ask the user to choose multiple software, the attacker can imitate the real software icon and name to attract users to click, if the service is called, the system will randomly Select a service; If receiver is called, the system will send the intent to these receiver one at a--

After hijacking the call, the attacker can (but not always succeed):

    • Start a fake software interface, expand phishing attacks (for example, require users to enter account passwords)

    • Read data carried by intent

    • Intercept the further transmission of the broadcast, causing the real receiver to fail to receive the message, thereby denying the service

    • If you invoke a false activity with Startactivityforresult (), you can return a malicious or false result to the caller

    • Execute other malicious code

Limited to space, we do not provide sample code for these situations. Take a look at how to solve this kind of problem.

No implicit invocation is required

In addition to implicit calls based on actions already in the intent class, the vast majority of implicit calls fall into both cases: calls from different components in the same software, and calls between different software from the same developer.

In both cases, in fact, development time has been able to determine which component to invoke. Therefore, you can avoid implicit calls instead of explicit calls based on component names.

An implicit call is required

Send broadcast in addition to using Sendbroadcast (Intent), there is also a method of Sendbroadcast (Intent, String), and its second parameter can specify the permissions that the recipient needs.

If you are invoking activity or service, as far as I know, there is no simple way to implement the recipient's permission limit. It is proposed in the Android documentation that you can customize binders and aidl to enable mutual verification of both sides of the communication, but the real implementation is not easy and is not recommended by the authorities.

Data validation

Whether you are a client or a server, you should first judge and validate the validity of the data before processing the data that is obtained externally. The main point here is whether to include malformed data.

In web development, the server needs to validate the data submitted by the user, otherwise it is easy to have well-known attacks such as SQL injection. It is no exception in mobile development. Although the client and server are transparent and invisible to the user on the underlying communication protocol, developers should not assume that the data transmitted by both parties will always be consistent with the pre-design. Similarly, validation should be performed before using the input that the user entered from the UI element, reading the data stored locally.

Software copyright protection

The attacker's reverse analysis of the Android software, in addition to the search for security vulnerabilities, can also directly attack the software itself.

    • Crack the charging mechanism, license verification or function limitation of the software;

    • Modify the software code, remove the ad library, or modify the ad library (usually change the referral ID field), or add the ad library, and then repackage and distribute;

    • Repackaging, embedding malicious code and distributing it;

    • Reverse analysis, learn how to implement the features of the software, or obtain reusable code;

A variety of measures can be taken to increase the difficulty of cracking, modifying and reverse analysis, reducing the likelihood of being attacked. These measures include:

    • Use code obfuscation tools, such as the SDK band's Proguard and other Java obfuscation.

    • Develop core modules with NDK.

    • Use official or third-party software protection programs, such as the SDK's ANDROID.DRM package, Google Play's software license (application Licensing) support.

    • Remove the debug code from development, turn off the debug switch, and delete the extra log code.

However, the adoption of these measures does not mean that it is foolproof. For example, the native code developed with the NDK can be disassembled, recompiled, and debugged using IDA Pro and its plug-ins, and with Google's DRM scheme, there are also antilvl tools like this. Theoretically, the existing defenses may find ways to continue the attack, the value of which is only to improve the attack difficulty and cost.

Summarize

Threats that have arisen and will arise

So far, in addition to academic research, attacks on Android software vulnerabilities have only come together-Faceniff, a hacker tool that hijacked many foreign social networking site client landing sessions. But as the cost and revenue of the attackers ' production of malicious code increases and their revenues fall, and mobile terminal privacy data becomes a trading resource for the underground industry chain, attacks against Android's popular software vulnerabilities will almost certainly occur and erupt in the next few years.

A unified security model

Confined to space, this article only describes a few common and simple security issues, there are many we know, still do not know the loopholes. How do I find and solve these problems?

Looking back at what we've covered, we can see that they have a similar security model: trust issues on both sides of the communication.

    • In the data store, the code that reads and writes data and the data stored locally are not trusted by each other.

    • In data communication, the sender and the recipient are not trusted by each other.

    • In login authentication, the user who initiated the authentication request and the server that received the authentication request are not trusted with each other.

    • In inter-component communication, the component initiating the intent is not trusted with the components that receive the intent.

    • In data validation, the module that processes the data cannot trust the source that produces the data.

In the face of future problems, we can also try to abstract this model, distinguish between untrusted entities, and then on the basis of untrusted, insecure, as far as possible to achieve relative credibility and security.

Further learning and action

Android Development documentation Best practices:designing for security and source document Tech Info:security introduces the security mechanism of the system from the point of view of development and system implementation respectively. In addition, Viaforensics provides an online tutorial called 42+ Best practices:secure Mobile development for IOS and Android, which describes in more detail the security threats that mobile software faces, And the practice strategy of security development is given.

On the community side, Stack-overflow is not necessarily a good choice from the standpoint of Android security development-some of the best answers don't take security into account, and direct use can create problems. Google Group's Anroid-security-discuss discussion group is more professional and accurate. Owasp has set up a Mobile security working group that has published several white papers, including top Ten Mobile risks, and has held appsec meetings. The efficiency of the Working Group is not high, but the quality of the output is very good.

On the academic front, the four major conferences of the 2011 and 2012 and the work-shop of mobile software vulnerability mining and attack prevention have emerged, from which the related Works section can be integrated to quickly understand the ideas of academia.

The current mobile development has not yet formed such a mature system, which may be related to its brisk and agile Internet product development style. But I believe that the real results of mobile software security development, will eventually be integrated into the requirements analysis, system design, development implementation, test verification, deployment operations and other aspects, and the PC platform SDL.

Android software Security Development Practices (next)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.