Thin dumpling dance · 2015/02/14 12:41

0 x00 science


A Service is an application component that has no interface and runs in the background for a long time. Components of other applications can start a service that runs in the background and continues to run even if the user switches to another application. In addition, a component can bind to a service to interact, even if the interaction is interprocess communication. For example, a service might handle network things, play music, perform file I/O, or interact with a content provider, all in the background.

0x01 Knowledge Points


The life cycle

StartService () creates service and bindService() creates service. StartService and bindService can both start services, so what’s the difference between them? The difference between the two is that the Service cycle changes. A Service started by startService must have stopService to terminate the Service. If you do not call stopService, the Activity ends while the Service is still running. A Service started by bindService can be terminated by unbindService or automatically terminated by onDestroy after the Activity ends.

The key way to

  • OnStartCommand () The system calls this method when another component, such as an activity, requests the service to start by calling startService(). Once this method is executed, the service starts and runs in the background for a long time. If you implement it, you are responsible for stopping the service when it completes its task, by calling stopSelf() or stopService(). You do not need to implement this method if you only want to provide bindings.

  • OnBind() The system calls this method when a component calling bindService() wants to bind to a service (for example, to perform interprocess communication). In your implementation, you must provide a return IBinder so that clients can use it to communicate with the service. You must always implement this method, but if you do not allow binding, you should return NULL.

  • OnCreate() This method is executed by the system when the service is first created to perform initialization that is run only once (before calling its methods such as onStartCommand() or onBind()). If the service is already running, this method will not be called.

  • OnDestroy() The system calls this method when a service is no longer in use and is about to be destroyed. Your service should release resources in this method, such as threads, registered listeners, sinks, and so on. This is the last call received by the service.

  • public abstract boolean bindService (Intent service, ServiceConnection conn, int flags)

    BindService uses the BindService () method to bind the service. The caller is bound to the binder and terminates once the caller (all) exits the service.

  • startService()

    The startService() method returns immediately and the Android system calls the onStartCommand() method of the Service. But if the service is not already running, onCreate() is called, followed by onStartCommand().

  • protected abstract void onHandleIntent (Intent intent)

    Call the worker thread to process the request

  • public boolean onUnbind (Intent intent)

    Called when all clients are disconnected from the interface published by the service. The default implementation does nothing and returns false.

extends

  1. Service

    This is the base class for all services. When you derive this class, it is important to create a new thread in the Service to do all the work. Because this service uses your application’s main thread (UI thread) by default, this will slow down the performance of all activities running in your application

  2. IntentService

    This is a subclass of Service that uses a worker thread to handle all startup requests, one at a time. This is the best option if you don’t need your Service to handle multiple requests simultaneously. All you have to do is implement onHandleIntent(), which receives the intent from each launch request, so you can do the background work.

form

  1. Started

    A service is “started” when startService() is called by an application component (such as an activity). Once run, a service can run in the background indefinitely, even if the component that started it is destroyed. Typically, a StartedService performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is complete, the service itself stops

  2. Bound

    A service is in the “bound” state when an application component calls bindService(). A BoundService provides a client-server interface that allows components to interact with services, send requests, get results, and even cross these interactions through interprocess communication. A BoundService runs only if another application’s component is bound to it. Multiple application components can be bound to a service at the same time, but the service is destroyed when all competing components are no longer bound.

Bound Service

When creating a service that provides bindings, you must provide an IBinder that the client uses to interact with the service. There are three ways you can define this interface:

  1. Derived from the class Binder

    If your service is private to your application and runs in the same process as the client (as it usually does), you should create your interface by deriving it from Binder and returning an instance of it from onBind(). Clients receive this Binder and use it to directly manipulate the public interface of the Binder or even Service implemented.

    This is best when your service is just a background job and only serves your own application. The only reason you can’t create your interface in this way is if your service is used by other applications or is cross-process.

  2. Using a Messenger

    If you want your interface to work across processes, you can create an interface for the Service with Messager. In this way, the Service defines a Handler that is responsible for the different types of Message objects. This Handler is the basis on which Messenger can share an IBinder with clients, allowing clients to send commands to servic using Message objects. Clients can define their own Messenger so that the Service can send messages back.

    This is the easiest way to perform IPC because Messenger queues all requests into one thread, so you don’t have to design your service to be thread-safe

  3. Use AIDL

    AIDL(Android Interface Definition Language) does all the work of breaking objects into a basic body that the operating system understands and marshals across processes to perform IPC. Using a Messenger, as described above, is actually based on AIDL. As mentioned above, Messenger creates a queue in a thread that holds all client requests, using Service to receive only one request at a time. However, if you want your Service to handle multiple requests at the same time, you can use AIDL directly. In this case, your service must be multithread safe.

    To use AIDL directly, you must create an.aidl file that defines the interface to the program. The AndroidSDK tools use this file to generate an abstract class that implements the interface and handles IPC, which you then derive in your service.

    Note: Most applications should not use AIDL to handle a bound service, as it may require multithreading capability and make implementation more complex. Likewise, AIDL is not suitable for most applications and this document does not discuss how to use it in your services. If you are sure you need to use AIDL directly, see the AIDL documentation.

Pay attention to

You do not need to specify any Intent filters if you intend to use your own service only within your application. Instead of using an Intent filter, you must start your service with an intent that explicitly specifies the class name of the service.

Alternatively, you can guarantee that your service is private by including the Android: Exported property and specifying the value “false”. This works even if your service uses an Intent filter.

When a service is started, its life is no longer dependent on the component that started it and can run independently in the background, even if the component that started it is dead. So, the service should stop itself by calling stopSelf() after it has finished its work, or other components can stop the service by calling stopService(). If the service does not provide binding, the intent passed to startService() is the only communication between the application component and the service. However, if you want the service to send a result back, the client that started the service can create a PendingIntent for broadcast (using getBroadcast()) and then pass it to the service in the intent. The service can then use broadcasts to send the results back and forth.

0x02 Security Suggestion


Service classification

Public service: can be called by any application cooperative service: can be called only by trusted applications internal service: can be called only by internal applicationsCopy the code

Intent-filter and exported are recommended

Conclusion:

The exported attribute specifies that a private service does not define an intent-filter and is set to false. The exported service is set to true. The intent-filter can be specified or not Internal/cooperative services set exported to true,intent-filter is not definedCopy the code

rule book

  1. Services that are used only by the application itself should be set to private

  2. The data received by the service must be processed with caution

  3. The protectionLevel of the signature level is used to check whether internal services are not invoked

  4. Should not be in the service to create (onCreate method is called) when deciding whether to provide services, should be in onStartCommand onBind/onHandleIntent judgment method is invoked.

  5. When the service returns the data, the app that receives the data is judged to be at risk of information leakage

  6. Use display intents when there is an explicit service to invoke

  7. Try not to send sensitive information

  8. The cooperation service shall verify the app signature of the cooperation company

0x03 Test Method


  1. Unlike broadcast receicer, a service can only be registered statically. You can decompile the configuration file Androidmanifest. XML to determine the service. If the service is exported, go to the next step

  2. Methods to check the service class, focus on the onCreate/onStarCommand/onHandleIntent method

  3. Retrieves the startService/bindService methods and the data they pass from all classes

  4. Write a test POC based on the business situation or test directly using ADB commands

0 x04 case


Case 1: Permission promotion

  • WooYun: Any software package installation and deletion of lePhone vulnerabilities
  • WooYun: Red Rice mobile phone Kingsoft Cleaning master application memory clearance permissions leak vulnerability
  • WooYun: Cheetah Cleanup Master memory cleanup permissions leak vulnerability

Case 2: Services hijacking

Attack Principle: Services are implicitly started. If services of the same name exist, the services installed first takes precedence

Attack model

Case 3: Denial of service

  • WooYun: snowball Android client null pointer exception and information leakage holes (Java. Lang. NullPointerException null pointer exception.)

Crash: When an intent is passed into an object, the intent’s translation fails.

Serializable:

Intent i = getIntent(); if(i.getAction().equals("serializable_action")) { i.getSerializableExtra("serializable_key"); // No exception is found}Copy the code

Parcelable:

this.b =(RouterConfig) this.getIntent().getParcelableExtra("filed_router_config"); // Causes the transition to crash abnormallyCopy the code

If malformed data is passed into POC, crash can be caused.

Case 4: Message forgery

  • WooYun: Youku Android 4.5 client upgrade vulnerability

0 x05 reference


Blog.csdn.net/niu_gao/art…

Developer.android.com/reference/a…

Developer.android.com/guide/compo…