Subject: Re: verified executable kernel modification committed
To: Thor Lancelot Simon <tls@rek.tjls.com>
From: Brett Lymn <blymn@baesystems.com.au>
List: tech-security
Date: 11/04/2002 23:03:13
On Mon, Nov 04, 2002 at 12:39:01AM -0500, Thor Lancelot Simon wrote:
> 
> No, you don't get a guarantee of that -- not unless you know that
> each and every last bit of code involved in doing the notification
> is valid as well.
>

Technically, that is not an insurmountable thing - drop safe logging
box monitoring the console output (the violations are kernel printf's)
would do the job.  I think that a bit extreme but not infeasible.

>  Though, to an extent, as Perry said, "it's turtles
> all the way down!" this very concern is why, for example, FIPS 140
> requires that you validate _all_ of the executables before you use
> _any_ of them -- and the fact that the ability to overwrite the
> _files_ would imply a protection failure that would, very likely,
> also allow overwriting the _fingerprints_, is why, generally, relying
> on run-time rechecking of the fingerprints to detect some sort of
> system compromise is highly likely to lend only a false sense of
> security.
> 

Boot from cdrom, validate the fingerprint list against the disk media,
load the fingerprints remount the now validated hard disk and go for
it.  If you fingerprint the files they will not be allowed to be
overwritten ...note not just executables - a file can be fingerprinted
and read denied if the fingerprint does not match, any file
fingerprinted is automatically read only.

> 
> File flags don't stop it _and_ your code doesn't stop it.  That's
> my point.
>

I know, you are proposing a total and utter breach of the kernel's
control over the hardware and then telling me what I have done is bad
because it cannot prevent that any more than the existing security
mechanisms can.  I find it hard to comprehend how that can be used as
an argument for not doing what I have done.
 
> 
> No, I'm pointing out that one real _advantage_ of your method is that
> it can extend the protection domain of your kernel beyond the physical
> hardware in the box.  You cannot prevent a nefarious individual from
> overwriting files stored across a shared network -- but, if implemented
> differently, your method could ensure that the code was no longer
> recognized as valid for execution.

OK - maybe I was too hasty here, the NFS thing was not something that
I really considered useful.  I was thinking that you would have to
fingerprint each page and load that into a file somewhere and stuff
that back into the kernel later... that would suck.  Another approach
would be to generate the page fingerprints on the fly - evaluate the
overall hash of the file and _while_doing_that_ generate fingerprints
for the individual pages (so that there is no race between the two
hash generations), if the overall hash matches then the list of page
fingerprints must be ok too (assuming the hash used is secure enough).
These fingerprints can then be used when a page is read back in to
verify the page is ok - a verification failure would cause the
execution to terminate.  The page-in code would need to be modified
but not too much...

>  The caching that improves performance
> in the local-disk case is the only thing that's costing you the very
> real and useful ability to protect the remote-filesystem case; and, from
> my point of view, as currently implemented, in the local-disk case, the
> code is an interesting experiment that, in essence, duplicates 
> functionality already provided by the simpler file-flags mechanism.
> 

I understand that but I find the lack of notification by the
file-flags mechanism to be a downside.  The threat model I was aiming
at was an infrastructure style machine coming under attack over the
network and either some sort of buffer overflow being used to exec
/bin/sh (say) or if they managed to crack the machine some tools being
loaded and execution of these tools attempted.  With what I have done
you will start getting kernel messages indicating something is wrong,
with file-flags there will be no indication anything is wrong at all.

> 
> To actually know that the system image is correct, it is necessary to
> validate it against an _external_ cryptographic checksum, using an
> _external_ validation mechanism.  When I say "external" here, I mean
> "provably unmodifiable by the running system".  Note that storing a
> checksum or signature list on read-only media isn't sufficient,
> because the _code that runs it_ needs to be on read-only media; and
> once it is loaded into memory, to actually have "assurance" in the
> way in which you've defined it, the system must provably enforce the
> restriction that the code cannot be modified and _will actually be run
> when requested_.
>

As I said above, I believe that, if required, that this is a feasible
thing to do.  Booting from ro media, doing the validation and then
running from hard disk would not be impossible to do.  You don't want
to just run from cdrom because even though cdrom's are fast at peeling
data off in a serial stream their random seek ability still sucks.
 
> 
> If "assurance", as you've defined it, is your goal, one good thing to
> read might be the power-up and continuous self-test requirements for
> FIPS 140 conformant cryptographic devices (which includes a lot more
> things these days than you might expect, for example several 
> garden-variety network routers from Cisco, Nortel, or even my own
> employer).

Yes, I just read that...I have done a software design for a machine
whose primary role in life was to check that it was operating
correctly (as far as possible), it's other functions were mere
interruptions (literally) to it's main role of self testing.

> It is at least as interesting to read about how some of these devices 
> have been _defeated_ as it is to read about how they were designed to
> be unmodifiable.  Interesting, but rather depressing. ;-)
>

Interesting indeed and it does explain the reasons behind some
characteristics of some equipment I have handled in the past.  I
really was not aiming for that level of assurance - my primary aim was
to prevent a machine being owned by a script kiddie and make it
tougher for the more determined person.
 
> 
> I think this is actually orthagonal to your original purpose, but I'd hardly
> attempt to dissuade you from investigating it nonetheless. ;-)
>

Yes, signing binaries is indeed othogonal to where I wanted to go.  I
know that others are interested in looking at doing this, I did
express interest to them in helping out.
 
> 
> I think I actually have a pretty good understanding of what you're trying
> to do; my concern is that you may have persuaded yourself you've achieved 
> your goal when you may not actually have achieved it.
>

No, what I have committed is really only the beginning, I stated that
it was nowhere near finished in the first message I put out.  I
committed the code because I believed it at a point where it could do
something useful enough for others to prod at.

>  Trusting a system to
> validate itself when there is only a single domain of protection is a very,
> very dangerous thing to do;

Yes, I agree, it is dangerous but if you only have a single domain
then you need to evaluate the risks in trusting what you have.  What I
have done helps mitigate those risks more than the current file-flags
implementation does.

> trusting that it is valid because it hasn't
> told you it is not strikes me as more so.

Well, if you really want there is a verbose debug mode that prints a
message for each valid fingerprint and dumps out the loaded
fingerprint list.  I turned those off by default because I believed
the output to be too verbose.

> and that those boundaries are sufficient to prevent the system
> from being modified, including the kernel itself, is false, you can't
> trust files marked with 'schg' to be the same files you think they are,
> but you can't trust your code to tell you they aren't, either.

Yes I do understand that.  I have always held the view that if the
kernel's control of the underlying devices is not absolute then
_nothing_ you can do in software will be effective because the
attacker can just twiddle the bits away from your control.  

I really was wanting to make this more a "tamper evident" system,
where there would be an alert when the system was tampered with - that
was the whole reasoning behind fingerprinting the files, you had
something to go back to and verify against (modulo your kernel being
untampered with).

>  I am not
> trying to beat you about the head with anything but my own frustration
> that what you're trying to do would be very, very useful -- but that it
> is very hard to get right, and that I'm not sure you're quite there yet.
> 

I know I am not there yet.  I do want this to be useful.  My own
frustration comes from people ignoring what I think is a useful
feature... that verified exec will _tell_ you when it does not like
something, file-flags does not do that.

-- 
Brett Lymn