securing / SimpleXPCApp

Secure example of an XPC helper written in Swift
https://securing.biz/
MIT License
99 stars 6 forks source link

Alternative to auditToken #1

Open Kentzo opened 4 years ago

Kentzo commented 4 years ago

Earlier this month an Apple employee posted an update to ADC where he suggested an alternative to using the audit token:

You can use the public API to get the process ID from the connection (processIdentifier or xpc_connection_get_pid) and create your code object from that using kSecGuestAttributePid. In this case, design your IPC protocol to not accept any security-critical requests as the first message on the connection.

The idea being only the 1st message over the connection is vulnerable.

What's your opinion on that?

r3ggi commented 4 years ago

IMO it's a bad idea to use the PID because an attacker can fork a lot of times, enqueue a lot of XPC messages and then replace the image to the right one. (The attacker doesn't have to wrap PIDs)

Let's take a look at the following example:

XPC Messages Queue Connection 1: Message 1 Connection 1: Message 2 Connection n-1: Message 1 Connection n-1: Message 2 Connection n: Message 1 Connection n: Message 2
Validation Failed Failed Failed/Passed Failed/Passed Passed Passed

Even if the security-critical request is sent in the 2nd message, the attacker will still be able to win the race.

I talked with a guy from Apple Security about the non-public audit_token APIs. We have to wait for them. 😊 But until Apple releases public APIs, I'd recommend using the private ones...

Kentzo commented 4 years ago

As I expressed in that thread, I'm completely puzzled in what "reliance on the n-the message being from the original connection" has to do with a race for the PID at all.

Do you see how "validity" of an XPC connection can help mitigate the attack?

r3ggi commented 4 years ago

Probably the Apple's employee assumed that the attacker will not be able to enqueue more than 1 message in the same connection. So the assumption was that in the 2nd message you will make another validation that will prove that the client's process is signed with another certificate (so you will invalidate the whole connection).

Kentzo commented 4 years ago

Is it something that was proved to be wrong? Assuming the OS enqueues exactly 1 messages for user's handler and validates the XPC connection by checking whether the peer is still alive, it should be sufficient.

I realize that in the example above you implied that no such validation happens, but is it just a theory?

r3ggi commented 4 years ago

Assuming the OS enqueues exactly 1 messages

AFAIK if you make a lot of XPC connections the OS will enqueue more than 1 message in 1 connection (if you of course send more messages)

checking whether the peer is still alive

The peer will be still alive always in that attack. I'm considering the case where the peer uses the posix_spawn() with POSIX_SPAWN_SETEXEC flag instead of the PID wrapping (dying and getting a PID of the died process)

You can read more about this attack in my post

Kentzo commented 4 years ago

AFAIK if you make a lot of XPC connections the OS will enqueue more than 1 message in 1 connection (if you of course send more messages)

I'm not aware of the internals, but I assume there are at least 2 queues involved:

  1. Queue in front of OS XPC processing facilities
  2. Queue in front of user's XPC event handler

The peer will be still alive always in that attack. I'm considering the case where the peer uses the posix_spawn() with POSIX_SPAWN_SETEXEC flag instead of the PID wrapping (dying and getting a PID of the died process)

Wouldn't it invalidate connection preventing the OS from delivering the 2nd message?

I guess the only way to find out is to conduct a test to see whether it's possible to deliver 2 message with originating peer dying somewhere before the 1st message is received by user's XPC event handler.

benjamin-bader commented 2 years ago

I found this issue accidentally in a Google search (I have an XPC-based privileged helper, ergo have similar concerns), ad am happy to share two recent-ish developments:

Hopefully this proves useful here.

Kentzo commented 2 years ago

That's great!

I was looking for some sample code for these functions and found a discussion on Apple's Developer Forums