Chapter 20. NetBSD Veriexec subsystem

Veriexec is NetBSD's file integrity subsystem. It's kernel
based, hence can provide some protection even in the case of a root
compromise.

20.1. How it works

Veriexec works by loading a specification file, also called the
signatures file, to the
kernel. This file contains information about files Veriexec
should monitor, as well as their digital fingerprint (along with
the hashing algorithm used to produce this fingerprint), and
various flags that will be discussed later.

At the moment, the following hashing algorithms are
supported by Veriexec:
MD5,
SHA1,
SHA256,
SHA384,
SHA512, and
RMD160.

20.2. Signatures file

An entry in the Veriexec signatures file looks like
this:

/path/to/file algorithm fingerprint flags

Where the first element, the path, must always be an
absolute path. The algorithm is one of the algorithms listed
above, and fingerprint is the ASCII fingerprint.

20.3. Generating fingerprints

You can generate ASCII fingerprints for each
algorithm using the following tools:

Each entry may be associated with zero or more flags.
Currently, these flags indicate how the file the entry is describing
should be accessed.
Note that this access type is enforced only in strict level 2 (IPS
mode) and above.

The access types you can use are “DIRECT”,
“INDIRECT”, and “FILE”.

DIRECT access
means that the file is executed directly, and not invoked
as an interpreter for some script, or opened with an editor.
Usually, most programs you use will be accessed using this
mode:

%ls /tmp%cp ~/foo /tmp/bar%rm ~/foo

INDIRECT
access means that the file is executed indirectly, and is
invoked to interpret a script. This happens usually when
scripts have a #! magic as their first line. For example,
if you have a script with the following as its first
line:

#!/bin/sh

And you run it as:

%./script.sh

Then /bin/sh will be executed
indirectly -- it will be invoked to interpret the
script.

FILE entries
refer to everything which is not (or should not) be
an executable. This includes shared libraries,
configuration files, etc.

Veriexec allows you to specify more than one way to access a
file in an entry. For example, even though
/usr/bin/perl is mostly used as an
interpreter, it may be desired to be able to execute it
directly, too:

/usr/bin/perl MD5 914aa8aa47ebd79ccd7909a09ed61f81 DIRECT, INDIRECT

Shell scripts using #! magic to be “executable”
also require two access types: We need them to be
“DIRECT” so we can execute them, and we need them
to be “FILE” so that the kernel can feed their
contents to the interpreter they define:

/usr/src/build.sh MD5 e80dbb4c047ecc1d84053174c1e9264a DIRECT, FILE

To make it easier to create signature files, and to make the
signature files themselves more readable, Veriexec allows you to use
the following aliases:

Table 20.2. Veriexec access type aliases

Alias

Expansion

PROGRAM

DIRECT

INTERPRETER

INDIRECT

SCRIPT

DIRECT, FILE

LIBRARY

FILE

Sample scripts for generating fingerprints are available in
/usr/share/examples/veriexecctl. After you've
generated a signatures file, you should save it as
/etc/signatures, and enable Veriexec in
rc.conf:

veriexec=YES

20.4. Strict levels

Since different people might want to use Veriexec for
different purposes, we also define four strict levels, ranging
0-3, and named “learning”, “IDS”,
“IPS”, and “lockdown” modes.

In strict level 0, learning
mode, Veriexec will act passively and simply warn about any
anomalies. Combined with verbose level 1, running the system in
this mode can help you fine-tune the signatures file. This is
also the only strict level in which you can load new entries
to the kernel.

Strict level 1, or IDS
mode, will deny access to files with a fingerprint
mismatch. This mode suits mostly to users who simply want to
prevent access to files which might've been maliciously modified
by an attacker.

Strict level 2, IPS mode,
takes a step towards trying to protect the integrity of
monitored files. In addition to preventing access to files with
a fingerprint mismatch, it will also deny write access and
prevent the removal of monitored files, and enforce the way
monitored files are accessed. (as the signatures file
specifies).

Lockdown mode (strict level 3)
can be used in highly critical situations such as custom made
special-purpose machines, or as a last line of defense after an
attacker compromised the system and we want to prevent traces
from being removed, so we can perform post-mortem analysis. It will
prevent the creation of new files, and deny access to files not
monitored by Veriexec.

It's recommended to first run Veriexec in strict level 0 and
verbose level 1 to fine-tune your signatures file, ensuring that
desired applications run correctly, and only then raise the
strict level (and lower the verbosity level). You can use
/etc/sysctl.conf to auto raise the
strict level to the desired level after a reboot:

kern.veriexec.strict=1

20.5. Veriexec and layered file systems

Veriexec can be used on NFS file systems on the client side
and on layered file systems such as the union file system. The
files residing on these file systems need only be specified in the
/etc/signatures file and that the file
systems be mounted prior to the fingerprints being loaded.

If you are going to use layered file systems then you must
ensure that you include the fingerprint for files you want
protected at every layer. If you fail to do this someone could
overwrite a file protected by Veriexec by using a different layer
in a layered file system stack. This limitation may be removed in
later versions of NetBSD.

It's recommended that if you are not going to use layered
file systems nor NFS then these features should be disabled in
they kernel configuration. If you need to use layered file
systems then you must follow the instructions in the previous
paragraph and ensure that the files you want protected have
fingerprints at all layers. Also you should raise securelevel to
2 after all mounts are done:

kern.securelevel=2

To prevent new layers being mounted which could compromise
Veriexec's protection.

20.6. Kernel configuration

To use Veriexec, aside from creating a signatures file, you
should enable (uncomment) it in your kernel's config file: (e.g.
/usr/src/sys/arch/i386/conf/GENERIC):