version 1.6, 2015/06/19 19:18:31
|
version 1.7, 2021/04/12 13:15:03
|
Line 1
|
Line 1
|
**Contents** |
This page was moved to: |
|
[The NetBSD Guide - NetBSD Veriexec subsystem](//www.NetBSD.org/docs/guide/en/chap-veriexec.html) |
[[!toc levels=3]] |
|
|
|
# NetBSD Veriexec subsystem |
|
|
|
[[!template id=man name="veriexec" section="8"]] |
|
is a file integrity subsystem in NetBSD (introduced in 3.0). It is kernel |
|
based, hence can provide some protection even in the case of a root compromise. |
|
|
|
## How it works |
|
|
|
First of all (usually at boot time), Veriexec loads 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. |
|
|
|
Then, whenever an application tries to open a file, there is a |
|
[[!template id=man name="kauth" section="9"]] check |
|
before actually doing so if the application is permitted to do so. Veriexec |
|
hooks in here and checks whether the file has the fingerprint as recorded in |
|
the signature file. If not, it acts depending on its mode, e.g., it could deny |
|
file access if the fingerprints mismatch. |
|
|
|
To secure your system with veriexec, you need a kernel with the option |
|
`veriexec` enabled (as it is in the default kernel), and you need support for |
|
the algorithms you want to use (by default, all are activated). Then, you |
|
decide which files you want to monitor, generate a signatures file and make it |
|
load at boot. |
|
|
|
## Signatures file |
|
|
|
An entry in the Veriexec signatures file looks like this: |
|
|
|
/path/to/file algorithm fingerprint flags |
|
|
|
With |
|
|
|
* `/path/to/file` is the absolute (!) path to the monitored file. |
|
* `algorithm` is the used algorithm. It is one of `MD5`, `SHA1`, `SHA256`, |
|
`SHA384`, `SHA512`, `RMD160`. |
|
* `fingerprint` is the signature of the file. |
|
* `flags` describe the monitoring type of the file, as described below. |
|
|
|
### Generating fingerprints |
|
|
|
You can generate ASCII fingerprints for each algorithm using the following |
|
tools: |
|
|
|
* **MD5** -- `/usr/bin/cksum -a md5` |
|
* **SHA1** -- `/usr/bin/cksum -a sha1` |
|
* **SHA256** -- `/usr/bin/cksum -a sha256` |
|
* **SHA384** -- `/usr/bin/cksum -a sha384` |
|
* **SHA512** -- `/usr/bin/cksum -a sha512` |
|
* **RMD160** -- `/usr/bin/cksum -a rmd160` |
|
|
|
For example, to generate a MD5 fingerprint for `/bin/ls`: |
|
|
|
% cksum -a md5 < /bin/ls |
|
a8b525da46e758778564308ed9b1e493 |
|
|
|
And to generate a SHA512 fingerprint for `/bin/ps`: |
|
|
|
% cksum -a sha512 < /bin/ps |
|
381d4ad64fd47800897446a2026eca42151e03adeae158db5a34d12c529559113d928a9fef9a7c4615d257688d1da4645db004081030d7f080bb7198067eb890 |
|
|
|
#### veriexecgen |
|
|
|
[[!template id=man name="veriexecgen" section="8"]] |
|
is a tool which automatically creates fingerprints for files or directories. |
|
By default, it will create SHA256 fingerprints for `/bin`, `/sbin`, `/usr/bin`, |
|
`/usr/sbin`, `/lib`, `/usr/lib`, `/libexec` and `/usr/libexec` and save them to |
|
`/etc/signatures`. |
|
|
|
You can also specify other algorithms and directories to be searched, e.g., you |
|
might want to include fingerprints of the packages you installed (though you |
|
have to be careful to recreate fingerprints on the next package update!). |
|
|
|
### veriexecctl |
|
|
|
For controlling the database inside the kernel, you have the tool |
|
[[!template id=man name="veriexecctl" section="8"]]. |
|
It can be used for dumping the whole database (`dump`), flushing it (`flush`), |
|
i.e., deleting all entries in the kernel's table, query an entry, etc. |
|
|
|
### Flags |
|
|
|
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 |
|
|
|
`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 # `ls` is the executed file |
|
$ cp ~/foo /tmp/bar # `cp` is the executed file |
|
$ rm ~/foo # `rm` is the executed file |
|
|
|
#### INDIRECT |
|
|
|
`INDIRECT` access means that the file is executed indirectly, and is invoked to |
|
interpret a script. This happens usually when scripts have a shebang (`\#!`) |
|
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 |
|
|
|
`FILE` entries refer to everything which is not (or should not) be an |
|
executable. This includes shared libraries, configuration files, etc. |
|
Everything you want to have monitored. |
|
|
|
### Examples |
|
|
|
Some examples for Veriexec signature file entries: |
|
|
|
/bin/ls MD5 dc2e14dc84bdefff4bf9777958c1b20b DIRECT |
|
/usr/bin/perl MD5 914aa8aa47ebd79ccd7909a09ed61f81 INDIRECT |
|
/etc/pf.conf MD5 950e1dd6fcb3f27df1bf6accf7029f7d FILE |
|
|
|
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 data=""" |
|
`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 |
|
|
|
## 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. |
|
|
|
* *strict level 0* is the *learning mode*. In this level, 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* is the *IDS mode* (Intrusion Detection System Mode). Now, |
|
Veriexec 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*, the *IPS mode* (Intrusion Prevention System Mode): This |
|
level 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). |
|
|
|
* *strict level 3*, named *Lockdown mode* is the most restricted mode. |
|
Lockdown mode 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 and getting used to Veriexec, 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 |
|
|
|
Or you can also increase while the system is running (though this undermines |
|
some of the security Veriexec provides): |
|
|
|
sysctl -w kern.veriexec.strict=1 |
|
|
|
## Veriexec and layered file systems |
|
|
|
Veriexec can be used on NFS file systems on the client side and on layered file |
|
systems such as nullfs. 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, 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, you have to follow the instructions in the |
|
previous paragraph and ensure that the files you want protected have |
|
fingerprints at all layers. You should also raise securelevel to 2 after all |
|
mounts are done to prevent new layers from being mounted, which could |
|
compromise Veriexec's protection: |
|
|
|
kern.securelevel=2 |
|
|
|
## Kernel configuration |
|
|
|
To use Veriexec, aside from creating a signatures file, you need a kernel with |
|
Veriexec enabled. It is already enabled in the default (*GENERIC*) kernel, but |
|
if you built your own one, you have to uncomment the following line in the |
|
configuration: |
|
|
|
pseudo-device veriexec |
|
|
|
Then, you need to enable the hashing algorithms you wish to support: |
|
|
|
options VERIFIED_EXEC_FP_MD5 |
|
options VERIFIED_EXEC_FP_SHA1 |
|
options VERIFIED_EXEC_FP_RMD160 |
|
options VERIFIED_EXEC_FP_SHA512 |
|
options VERIFIED_EXEC_FP_SHA384 |
|
options VERIFIED_EXEC_FP_SHA256 |
|
|
|
Depending on your operating system version and platform, these may already be |
|
enabled. Once done, rebuild and reinstall your kernel, see |
|
[[Compiling the kernel|guide/kernel]] for further instructions. |
|
|
|
If you do not have the Veriexec device `/dev/veriexec`, you can create it |
|
manually by running the following command: |
|
|
|
# cd /dev |
|
# sh MAKEDEV veriexec |
|
|
|