Re: Integrity checks for Mac kernel extensions
Re: Integrity checks for Mac kernel extensions
- Subject: Re: Integrity checks for Mac kernel extensions
- From: Evan Lojewski <email@hidden>
- Date: Sun, 26 Aug 2012 22:18:53 -0700
On Sun, Aug 26, 2012 at 10:04 PM, Arun <email@hidden> wrote:
> Hi Evan
>
> Can you please elaborate on the last part of your e-mail. I did not
> understand it fully.
>
>
> If you do want to do some integrity check, it may be better to do some
> sort of checksum on the actual loaded binary (say, use the address of
> a symbol or the __TEXT segment) instead of checking something that
> doesn't correspond to your binary. Also note that your binary will be
> modified in memory by the kernel, so that has to be taken into account
> as well.
>
Essentially, you cannot assume that the binary on disk corresponds to
the binary loaded int memory. It is very trivial for someone load the
same kext, just bin patched, without you knowing. What I was saying is
that it would be better to verify the actual code that is *running*
instead of the code that might have been loaded (since you don't know
if it really was loaded).
*If* you wanted to verify something, you it would be better to just
verify the actual memory. you can easily get the text address of your
code using something like the following (I'm assuming the linker will
cooperate, I haven't tried this in kernel. If not, there are other
ways to do the equivalent):
extern char text_start __asm("section$start$__TEXT$__text");
extern char text_end __asm("section$end$__TEXt$__text");
I was also saying that this really isn't feasible as well because the
kernel can and does modify your code when it gets loaded (the linker
will go and update function calls for one thing). You cannot just
simple perform a checksum and expect the value to be constant, it
won't be.
As has already been stated, It's also very trivial for someone to just
patch out your check. The only way you can assume that your kext is
not modified is if you can ensure a complete chain of trust from the
very beginning of the cpu execution. If the user has the ability to
run unsigned code (which they do, even on something like the iphone
with all of it's fancy security), you cannot ensure that your code has
not been modified. I don't care how many hashes or encryption schemes
you use, if someone wants to modify your code, they can. The best you
can do is to make it harder, which a simple integrity check does not
do. While I'm at it, someone could even just modify your kext *after*
it's been loaded and passed the integrity check.
Evan Lojewski
> Thanks
> Arun KA
>
>
>
> On Mon, Aug 27, 2012 at 1:04 AM, Evan Lojewski <email@hidden> wrote:
>>
>> There really isn't a way for you to detect that someone is or is not
>> tampering with your kext.
>>
>> If you are using an IOKit driver, someone can always subclass your
>> driver. This provides an easy way to modify the behavior of your kext
>> without touching the binary itself. If they don't want to do that,
>> they can always binpatch the binary to include whatever code they
>> wanted and either also patch out the check, or just point your kext to
>> look at an unmodified version of the binary.
>>
>> As already mentioned, you can use the vfs system calls to read in a
>> driver however you are never guaranteed that the file you are reading
>> from disk is the same one that was loaded into memory. Yes, if the
>> file was in a kernel cache or mkext, the cache includes that path that
>> mkext used for the kext inclusion, however as already stated, that
>> doesn't mean that either someone is lying to you or that the kext has
>> changed on disk back to the original after it was placed in the cache
>> to spoof your check. You also need to make sure the vfs subsystem is
>> initialized before you call into it, otherwise you may cause panics.
>> One easy way is to use the post root hook that is in the kernel
>> specifically for the BootCache.kext (note that this is a private api
>> and would not be recommended by Apple).
>>
>> If you do want to do some integrity check, it may be better to do some
>> sort of checksum on the actual loaded binary (say, use the address of
>> a symbol or the __TEXT segment) instead of checking something that
>> doesn't correspond to your binary. Also note that your binary will be
>> modified in memory by the kernel, so that has to be taken into account
>> as well.
>>
>> Evan Lojewski
>>
>> On Sun, Aug 26, 2012 at 12:23 PM, Arun <email@hidden> wrote:
>> > What is auto correct?
>> > Also yes integrity check is to make sure that some has not tampered with
>> > the
>> > kext.
>> > I am placing the kext in the /System/Library/Extensions and it is a
>> > IOKit
>> > driver for BlockI/O devices.
>> > So how can i read files from within this kext when it is trying to
>> > initialize when the system boots?
>> >
>> > Arun KA
>> >
>> > On Sat, Aug 25, 2012 at 12:47 AM, Evan Lojewski <email@hidden>
>> > wrote:
>> >>
>> >> Heh, autocorrect is useful... That should say prelinked kernel and not
>> >> prelim led,
>> >>
>> >> Evan
>> >>
>> >> On Aug 24, 2012, at 1:16 PM, Evan Lojewski <email@hidden> wrote:
>> >>
>> >> > I think a good question to ask here is *why* you want to do an
>> >> > integrity check. Do you just want to make sure that the Kext hasn't
>> >> > been corrupted? Additionally, if the Kext is loading from a prelim
>> >> > led
>> >> > kernel or cache, the binary itself may get modified.
>> >> >
>> >> > Evan Lojewski
>> >> >
>> >> > On Aug 24, 2012, at 1:08 PM, Ken Hornstein <email@hidden>
>> >> > wrote:
>> >> >
>> >> >>> You seem to be drawing conclusions based on writing a BSD
>> >> >>> filesystem
>> >> >>> kext (?) which is not the general case, and certainly has a
>> >> >>> different
>> >> >>> operating environment than 99% of kexts (which are IOKit kexts,
>> >> >>> match asynchronously with respect to the root filesystem and each
>> >> >>> other, and cannot in general call into the BSD side of the kernel
>> >> >>> early in boot without panicking)
>> >> >>
>> >> >> Well, yeah, that's my experience, and I hope I've never presented
>> >> >> myself
>> >> >> as the be-all expert when it comes to MacOS kernel extensions
>> >> >> because
>> >> >> obviously I'm not.
>> >> >>
>> >> >> My original point was that you can definitely access filesystems
>> >> >> from kexts, but I was under the impression that kext loading was
>> >> >> handled exclusively by kextd and friends and obviously everything
>> >> >> will be up and running by that time. As you've pointed out, that's
>> >> >> not a valid assumption; I learned something new today.
>> >> >>
>> >> >> It occurs to me that if your kext is loaded before the root
>> >> >> filesystem
>> >> >> is
>> >> >> mounted you could do somet goofy stuff like have a thread wait
>> >> >> around
>> >> >> until
>> >> >> it is available, but that probably falls under "here be dragons".
>> >> >>
>> >> >> --Ken
>> >> >> _______________________________________________
>> >> >> 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