Hello, My application monitors ES_EVENT_TYPE_NOTIFY_CLOSE. If a file is dragged to another location in Finder, the Endpoint Security reports the event ES_EVENT_TYPE_NOTIFY_CLOSE was performed by '/usr/libexec/xpcproxy'. So, xpcproxy is the process that performed ES_EVENT_TYPE_NOTIFY_CLOSE.
Sort of. xpcproxy is basically the "starter process" that XPC services are initialized from, however, it should be very quickly replaced by the "real" service (which does any actual work) and that "real" service is what I'd expect most events to be ascribed to.
I think what might have happened here is actually the the XPC service never actually closed the file (probably intentionally, as there's no reason to if you're going to exit), so the close actually happened during process destruction. That also meant that the activity was ascribed to "xpcproxy", when the "real" source was the original service
Looks like the dragged file is copied by some XPC service.
Yes, probably "DesktopServicesHelper", which is what does most of the Finder "real" file work (copies, emptying trash, etc).
I have found the audit user id is equal to user who dragged a file.
Can audit user id be used to identify a user who triggers copy file action in this case?
If no, are there any way to define such info?
First off, please go read "Inferring High-Level Semantics from Low-Level Operations". The kind of inference you're trying to make here is very common (and nearly unavoidable) in ES clients, but it's critical that you're aware that you are in fact making inferences based on the data available, not getting true "answers".
So, getting into specifics, your ES client is given two different audit tokens:
parent_audit_token-> This is the direct parent of the source process. For most app or XPC service launches, this will be launchd/pid 1. In practice, most of the processes on a system actually end up getting launched this way, which means it's not actually that interesting.
NOTE: If you're going to look at parent_audit_token, one trivial optimization is to check for launchd by comparing ppid (or original_ppid, depending on what you're interested in) to "1". PID reuse means this kind of comparison is not safe in the "general" case (this is why audit tokens exist), but is safe in the specific case of launchd. launchd will ALWAYS be pid 1 and pid 1 will ALWAYS be launchd*.
*Architecturally, launchd is pid 1 because the kernel doesn't create it through fork (you can't fork if no process exists) but instead creates it "manually" constructing it's process structure and then "directly" starting it's execution through the scheduler. This entire process is a "one time" initialization that happens early in the boot process and cannot really be "repeated". If launchd terminates, the kernel makes no attempt to recover from that but instead just reboots the entire system, making launchd exit'ing the functional equivalent of a restart.
responsible_audit_token-> This is the process that originally "asked" launchd to create the process which means, in practice, this is the process that's actually interesting. In the case of Finder file operations, I'd expect the Finder to be listed as the responsible process for the service and the user ID of the Finder would be the user to initiated the copy.
The one warning about this technique is this note in the documentation:
"The responsible process may be this process itself, if there’s no responsible process or the responsible process already exited."
That dynamic means that if you're trying to reliable track responsibility, you probably need to do that work "early" (probably at process creation), not "late" (when the parent may have been destroyed). More broadly, this is the kind of work that should be done once as part of the process your client uses to track activity over time, NOT "later" as part of individual event processing.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware