As far as i understand, an IsolatedProcess is here to run untrusted code.
But if the IsolatedProcess is basicly a process without any permissions, how can one send the untrusted code (lets say a class) to the IsolatedProcess?
I mean the IsolatedProcess have no access to the files in the device , to the internet, or anything else.
So what is the way to send the untrusted code to the IsolatedProcess?
I am trying to pass Constructors to the IsolatedProcess so he can start this untrusted classes safetly, but all the communication between processes must be with Serializable objects, and a Constructor is not a Serializable object.
You're misunderstanding the purpose of isolatedProcess. It doesn't provide APIs to do what you want because it isn't how it's intended to be used and using it like that wouldn't be a good security practice. It's designed to provide a layer of security that an attacker needs to bypass once they've gained remote code execution via an exploit. You simply shouldn't run untrusted Java code because Android isn't designed to do it. It will still have access to native APIs including the kernel's system calls, etc. within an isolatedProcess. isolatedProcess drops nearly all privileges (gets a unique UID / GID and runs in the isolated_app SELinux domain) but it's not a very good sandbox alone. If you're determined to do it, then doing it within isolatedProcess is better than outside it, but you would be rolling your own code for it.
The main user of isolatedProcess is Chrome. Each site instance is rendered by a separate isolatedProcess service. It doesn't run untrusted Java or native code. An attacker needs a remote code execution exploit to gain control over the isolatedProcess. Chrome also doesn't only rely on isolatedProcess for the second layer of defence. It uses a strict seccomp-bpf filter to greatly reduce kernel attack surface.
Related
Android Application Framework provides a whole bunch of system services, such as PackageManagerService, ActivityManagerSerive. Most of the services are in the System Server process. The framework also provides a whole bunch of APIs to apps in the form of a set of proxy classes, such that when an app invokes proxy.API_foo(), the invocation will be handled, through the Binder mechanism, as a Remote Procedural Call by one of the system services.
My question is that, since all the proxy classes are in the memory address space of the app process, isn't is vulnerable to attacks by a hacked app? E.g., I can overwrite the "this" pointer of a proxy class of interest, such that "this" points to an arbitrary virtual function table.
Does the system provide any write-protection for those proxy class objects, so that they cannot be manipulated?
You may be wondering why I asked this silly question. I am considering such scenario: assuming an app is well protected against reverse engineering, but by adding code that manipulates the memory storing the proxy classes, I can still hack the high-value app (say a banking app, a health care app) somehow by returning fake values when system service APIs are called.
I found this but don't quite get it:
http://shadowwhowalks.blogspot.com/2013/02/android-replacing-system-classes.html
I also found a paper:
http://ceur-ws.org/Vol-1575/paper_10.pdf
But the hacking requires the root privilege. Is that really necessary?
Links about System Services:
http://opensourceforu.com/2013/12/birds-eye-view-android-system-services/
https://www.slideshare.net/marakana/android-services-black-magic-by-aleksandar-gargenta
http://resources.infosecinstitute.com/practical-android-phone-forensics/#gref
I am developing android an app to detect malicious apps .we are planning to detect malicious apps based on the requested permission.....does permission alone will help us to detect malicious apps or do we need to consider characteristics like use of dynamic code, usage of static http url....any help appreciated. ...
I will breakdonw this question is several smallwer parts:
detect malicious apps
This is perhaps the harderst part in what you desire to do. Most anti virus, anti malware, etc. will usually search a "footprint" in the source code of the binary that is generating the instructions. If you found a number above threshold of footprints, you can guess that file is malware.
we are planning to detect malicious apps based on the requested permission
I am going to say explicitly: no...
As far as I have seem, most "weird" requests, are usually due to the programmers not fully understanding what the permission grants, or even why/what is necessary for.
This is so much an endemic problem, that Google itself changed how permissions work (if I am not mistaken, from K to L, or L to M or something in those updates)
Then again, an alarm app, that wants network access, wants to read all files in the system, wants to read/writte anything anywhere, wants to use your gps, etc etc, then that looks like malware on itself (and usually no READING user would use it).
do we need to consider characteristics like use of dynamic code
Yes. While Java itself cannot interpret its code "on-the-fly", DEX allows us to. And the most common hijacks are usually apps that do nothing, but then create an entry point to render javascript content, and perform some unexpected code.
usage of static http url
That is on itself not that much of a risk, since most browsers will request some security credential, and at least warn the user that he is on un-trusted network. A secondary problem that usually arrives is geerating the URL "on-the-fly" then asking an empty request to alter its request to that.
If an app is then requesting any web-based content bypassing the system (not a security issue, sometimes the programmer is simply making "less effort than necessary to fullfill a client request", then looking at static addresses, or even IPs is usually of no significant security value.
Can anyone put some light as what's the real/main advantage of introducing Isolatedprocess tag within Services in JellyBean[Android].
Is this advantageous at framework level or at the kernel level,as what we have seen that setting isolatedProcess tag value "true" within the Services assigns a new userId to that service process.
Have you seen Dianne Hackborn's answer on Google Groups? The question is identical and as she points out there is really one known use of that flags at this time: adding a layer of security for executing remote, untrusted code, i.e. JavaScript. There is no way to possibly guarantee that running remote code won't introduce security vulnerabilities, so by isolating the process that parses that code in a permission-less process, it becomes much more difficult for that code to do any real harm.
I am getting started on Android & iOS development and hence links to relevant resources will also be appreciated, just that I couldn't find anything much relevant.
Case Detail: I have to build an app that holds some critical information in a variable that is created, sent over a ssl-encrypted connection and destroyed. This variable shouldn't be read by any other process on the device. So far, I know of two cases that can happen:
[1] a service or program monitors the foreground app(which here would be my app) and then if it can inject some code(getting the foreground to bind to the rogue service for example) to read off the variable contents in question. I know OS safeguards exist, but are there any proofs out in the wild that demonstrate this ability of injecting code?
[2] a service or program monitors the network connections and logs the data being sent over the wire. Is there a possibility of apps reading network data like this? I know apps exist which can log the amount of data exchanged per app, but I have no clue as to whether they read system log files or actually monitor the connection.
It will be appreciated if details could be provided for both the platforms.
I work only with android, so this is valid for android only:
No, a service cannot inject code in foreground up, due to (at least) 2 reasons:
Each installed application gets it's own user id, and each process, and their data is protected by the user id. So one process cannot access the memory of another process. So no process can modify the memory either (by inserting code)
The java bytecode is converted to dalvik code, and stored in a place where only the system process can write. So no other process can inject code by changing the compiled dex files.
That is the protection provided by the system. Of course hackers might find an exploit in a certain library, and using buffer overflow might be able to run some snippet of code, but that's a different story. Also note that the data files of the process are private by default (no other process can see it), but processes could have read access to the code. Which means storing private keys in the code is probably not safe.
What is the advantage of using Binder for IPC over (Semaphores , Message Queue, PIPES) in Android stack?
Old question (and likely unmonitored by the poster), but worth answering:
A) All filesystem-based or filesystem-representable IPC mechanisms (notably pipes), can't be used because of a lack of a world-writable directory, where all processes can mkfifo/create the filesystem/socket representation of their IPC port (/dev/socket notwithstanding, which is used for system processes, e.g. rile, zygote, and their ilk).
B) None of the suggested mechanisms have the capability of "service location" which is required for Android. In UNIX, there's an RPC portmapper, and Android needs similar functionality. Enter: The ServiceManager, which can use binder to register as a context manager, to register/lookup service handles on the fly
C) There is an extensive need for serialization - be it intents, or other messages. Binder provides the parcel abstraction, which can be used for data marshaling by the Parcel.java.
D) SysV has other issues than Mr. Lambada's answer which are more paramount, notably race conditions, and lack of authorization.
E) Message queues and pipes can't pass descriptors. UNIX Domain sockets may, but can't be used because of (A) (again, unless you're root/system, like zygote, rild, installd..)
F) Binder is really lightweight, and has built-in authorization mechanisms. It also has nifty features like waking up the recipient process, as well as memory sharing, which the other mechanisms simply don't have. (and remember, no mmap(2), because of the file problem in (A) for named mappings).
and - let's not forget
G) Binder was started at Palm (ah, nostalgia) (q.v. OpenBinder). Ex-palmers got to Android, and brought their code in with them.
From the ndk's docs/system/libc/SYSV-IPC.html file:
Android does not support System V IPCs, i.e. the facilities provided by the following standard Posix headers:
<sys/sem.h> /* SysV semaphores */
<sys/shm.h> /* SysV shared memory segments */
<sys/msg.h> /* SysV message queues */
<sys/ipc.h> /* General IPC definitions */
The reason for this is due to the fact that, by design, they lead to global kernel resource leakage.
For example, there is no way to automatically release a SysV semaphore allocated in the kernel when:
a buggy or malicious process exits
a non-buggy and non-malicious process crashes or is explicitly killed.
Killing processes automatically to make room for new ones is an important part of Android's application lifecycle implementation. This means
that, even assuming only non-buggy and non-malicious code, it is very likely that over time, the kernel global tables used to implement SysV IPCs will fill
up.
At that point, strange failures are likely to occur and prevent programs that use them to run properly until the next reboot of the system.
Binders are used to to communicate over process boundaries since different processes don't share a common VM context => no more direct access to each others Objects (memory). Both parties within the same process (usually things that are within the same app) means (imho) that you should not use Binders since they slow down / complexify things unnecessary.
Binders are usually not used directly but rather via the "Service" or the "Messenger" classes. While communication with a Service is done via a full api of functions, the communication with a Messenger has to use "Message"s. Messengers a lot simpler to implement.
Apart from using Binders you can use anything that is available from any VM instance like "LocalSocket"s, Files, ContentProviders, Intents, ...
Binders are not ideal for transferring large data streams (like audio/video) since every object has to be converted to (and back from) a Parcel. All the conversion takes time. Much better in that case would be a LocalSocket for example.
Binders are used to enable remote procedure calls. You could implement RPC using the synchronization tools you mention but you would also need to write a lot of code to make it come together... with a Binder (normally only used within an Android Service) you have much less code to write; barely more than your actual remote functions.