Re: Authenticating a User Mode Daemon
Re: Authenticating a User Mode Daemon
- Subject: Re: Authenticating a User Mode Daemon
- From: Damien DeVille <email@hidden>
- Date: Wed, 04 Jan 2017 15:21:24 -0800
In user space you can use `SecCodeCopyGuestWithAttributes` to create a
code object referencing the running process. You need to pass it an
attributes dictionary that contains some process attribute so that the
Security framework can identify the process. For example, if you know
the pid you can create your code object like this (error handling
omitted):
```
pid_t pid = 12345;
CFDictionaryRef attributes = (__bridge
CFDictionaryRef)@{(id)kSecGuestAttributePid: @(pid)};
SecCodeRef code = NULL;
OSStatus status = SecCodeCopyGuestWithAttributes(NULL, attributes,
kSecCSDefaultFlags, &code);
```
pids are pretty volatile so you might want to use something more solid,
see the full list of supported attributes in Security/SecCode.h
Once you have this `SecCodeRef`, you can use `SecCodeCheckValidity` to
check its validity. You’ll probably also want to construct a
`SecRequirementRef` with your own requirements to pass to
`SecCodeCheckValidity` so that it can check that the code signature
satisfies these very requirements. The requirements can be anything,
like simply "anchor apple generic" or making sure that a certificate in
the chain matches your exact cert hash. See this doc for more info:
https://developer.apple.com/library/mac/documentation/Security/Conceptual/CodeSigningGuide/RequirementLang/RequirementLang.html)
```
CFStringRef reqs = CFSTR("anchor apple generic");
SecRequirementRef requirements = NULL;
status = SecRequirementCreateWithString(reqs, kSecCSDefaultFlags,
&requirements);
status = SecCodeCheckValidity(code, kSecCSDefaultFlags, requirements);
```
There might better ways to do that (and I’d love to hear them!) but I
think this should be enough to identify a process as something you sign
with your own certificate.
On Wed, Jan 4, 2017, at 02:02 PM, Josh Hight wrote:
> Hi Damien,
> Thank you so much for your help, I think you’ve got us 90% of the way
> there, but I have one point of confusion. How do I use the kauth_cred_t
> to verify that the code signature of the process is what we want it to
> be?
> Thanks,
> Josh Hight
> Security Engineer
> ThinAir Labs
> > Date: Wed, 04 Jan 2017 11:12:04 -0800
> > From: Damien DeVille <email@hidden>
> > To: email@hidden
> > Subject: Re: Authenticating a User Mode Daemon
> > Message-ID:
> > <email@hidden>
> > Content-Type: text/plain; charset=utf-8
> >
> > I had to deal with a very similar situation a few months ago and here’s
> > a brain dump of what I found out and the solution I went with.
> >
> > The kernel symbols necessary to perform code signature validation on a
> > process are not KPI (i.e. private) and attempting to link against them
> > will lead to kextd (justly) refusing to load the kext. So unless you’re
> > willing to somehow resolve these private symbols at runtime (don’t do
> > that!) you’re left with implementing signature validation in user space.
> >
> > Now, as Stéphane wrote, a good starting point if your user space daemon
> > is running as root, is to make your control socket `CTL_FLAG_PRIVILEGED`
> > so that you can already exclude a whole bunch of non-root processes from
> > connecting to the kext. You will still have to protect your user space
> > process from code injection. I believe Mach injection (when possible at
> > all, so against non-SIP processes that is) requires root to obtain the
> > task from pid so that should be safe. Regarding dyld injection, I think
> > you’ll want to make sure that your process is restricted (check for
> > https://opensource.apple.com/source/dyld/dyld-421.1/src/dyld.cpp for
> > more info) so that dyld doesn’t blindly load dylibs it find in the
> > `DYLD_INSERT_LIBRARIES` env variable. Note that if your binary is setuid
> > it should be restricted by default.
> >
> > If, as in my case, you also need non-root processes to connect to the
> > kext, you will need a root daemon (as described above) doing code
> > signature valdiation in user space and connecting to the kext on a
> > distinct `CTL_FLAG_PRIVILEGED` control socket. Then, whenever a regular
> > process attempts to connect to the kext on your usual control socket,
> > you would get its credentials, send them to the root daemon that would
> > perform signature validation on behalf of the kext and respond with a
> > yes/no answer. You can then decide whether to allow or deny the original
> > connection in your kext.
> >
> > Finally you also need to make sure that you can correctly resolve the
> > process creds/pid at control socket connection time. I’ve found that the
> > `ctl_connect` handler is invoked in the connecting process context so
> > calling `prod_self` and then `proc_ucred` and `proc_pid` should be safe
> > but worth keeping in mind that it might not always be the case?
> >
> > Thanks,
> > Damien
> >
> > On Wed, Jan 4, 2017, at 03:44 AM, Stéphane Sudre wrote:
> >>
> >> On 4 janv. 2017, at 07:10, Josh Hight wrote:
> >>
> >>> I have an application with two components, a Kernel Extension and a User-Mode daemon. I need to communicate information from the Kernel Extension to the User-Mode daemon. Since this is a security application and the information being communicated is sensitive I would quite like to verify that the information is communicated only with my User-Mode daemon. Is there any way to accomplish this?
> >>
> >> If the communication between your daemon and the Kernel Extension is
> >> performed via a control socket, the first step would be to set the
> >> CTL_FLAG_PRIVILEGED flag when you register your control socket (in the
> >> kext) so that only a root user-land process can communicate with your
> >> kext.
> >>
> >>
> >>
> >> _______________________________________________
> >> Do not post admin requests to the list. They will be ignored.
> >> Darwin-kernel mailing list (email@hidden)
> >> Help/Unsubscribe/Update your Subscription:
> >>
> >> This email sent to email@hidden
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Darwin-kernel mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden