92 lines
3.6 KiB
Python
92 lines
3.6 KiB
Python
import os
|
|
|
|
import infra.basetest
|
|
|
|
|
|
class TestAudit(infra.basetest.BRTest):
|
|
# This test needs a Kernel with the audit support (the builtin
|
|
# test Kernel does not have this support). Since the audit support
|
|
# enabled by default, a kernel fragment is not required.
|
|
config = \
|
|
"""
|
|
BR2_aarch64=y
|
|
BR2_TOOLCHAIN_EXTERNAL=y
|
|
BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0"
|
|
BR2_LINUX_KERNEL=y
|
|
BR2_LINUX_KERNEL_CUSTOM_VERSION=y
|
|
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.6.58"
|
|
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
|
|
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config"
|
|
BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y
|
|
BR2_PACKAGE_AUDIT=y
|
|
BR2_TARGET_ROOTFS_CPIO=y
|
|
BR2_TARGET_ROOTFS_CPIO_GZIP=y
|
|
# BR2_TARGET_ROOTFS_TAR is not set
|
|
"""
|
|
|
|
def test_run(self):
|
|
img = os.path.join(self.builddir, "images", "rootfs.cpio.gz")
|
|
kern = os.path.join(self.builddir, "images", "Image")
|
|
self.emulator.boot(arch="aarch64",
|
|
kernel=kern,
|
|
kernel_cmdline=["console=ttyAMA0"],
|
|
options=["-M", "virt",
|
|
"-cpu", "cortex-a57",
|
|
"-m", "256M",
|
|
"-initrd", img])
|
|
self.emulator.login()
|
|
|
|
# We check the program can run by showing its version. This
|
|
# invocation also checks the Kernel has the audit support
|
|
# enabled.
|
|
self.assertRunOk("auditctl -v")
|
|
|
|
# We define a normal user name for this test.
|
|
user = "audit-test"
|
|
|
|
# Audit rule inspired from auditctl manual page examples.
|
|
|
|
# We add an audit rule logging write access on the
|
|
# system password file.
|
|
cmd = "auditctl -a always,exit -F path=/etc/shadow -F perm=wa"
|
|
self.assertRunOk(cmd)
|
|
|
|
# We do a read-only access on this file, as the root user.
|
|
self.assertRunOk("cat /etc/shadow")
|
|
|
|
# We check our previous read-only access did NOT generated an
|
|
# event record.
|
|
ausearch_cmd = "ausearch --format text"
|
|
out, ret = self.emulator.run(ausearch_cmd)
|
|
self.assertEqual(ret, 0)
|
|
open_shadow_str = "acting as root, successfully opened-file /etc/shadow"
|
|
self.assertNotIn(open_shadow_str, "\n".join(out))
|
|
|
|
# We create a normal user. This will modify the shadow password file.
|
|
cmd = f"adduser -D -h /tmp -H -s /bin/sh {user}"
|
|
self.assertRunOk(cmd)
|
|
|
|
# We are now expecting an event record of this modification.
|
|
out, ret = self.emulator.run(ausearch_cmd)
|
|
self.assertEqual(ret, 0)
|
|
self.assertIn(open_shadow_str, "\n".join(out))
|
|
|
|
# We add a new audit rule, recording failed open of the system
|
|
# password file.
|
|
cmd = "auditctl -a always,exit -S openat -F success=0 -F path=/etc/shadow"
|
|
self.assertRunOk(cmd)
|
|
|
|
# We attempt to read the system password file as our new
|
|
# normal user. This command is expected to fail (as only root
|
|
# can root is supposed to read this file).
|
|
cmd = f"su - {user} -c 'cat /etc/shadow'"
|
|
_, ret = self.emulator.run(cmd)
|
|
self.assertNotEqual(ret, 0)
|
|
|
|
# Our last failed read attempt is supposed to have generated
|
|
# an event. We check we can see it in the log.
|
|
out, ret = self.emulator.run(ausearch_cmd)
|
|
self.assertEqual(ret, 0)
|
|
evt_str = f"acting as {user}, unsuccessfully opened-file /etc/shadow"
|
|
self.assertIn(evt_str, "\n".join(out))
|