From 98c701f33d8a83d7f408fc40da4faea0d936a653 Mon Sep 17 00:00:00 2001 From: Alexandre Pujol Date: Thu, 20 Jul 2023 23:45:14 +0100 Subject: [PATCH] feat(aa-log): show target in log, show access as owner too. --- pkg/logs/logs.go | 22 +++++-- pkg/logs/logs_test.go | 147 +++++++++++++++++++++++++----------------- tests/audit.log | 5 +- 3 files changed, 108 insertions(+), 66 deletions(-) diff --git a/pkg/logs/logs.go b/pkg/logs/logs.go index 048924c96..78203ab8a 100644 --- a/pkg/logs/logs.go +++ b/pkg/logs/logs.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/roddhjav/apparmor.d/pkg/util" + "golang.org/x/exp/slices" ) // Colors @@ -40,9 +41,8 @@ var ( repl string }{ {regexp.MustCompile(`.*apparmor="`), `apparmor="`}, - {regexp.MustCompile(`(peer_|)pid=[0-9]* `), ""}, - {regexp.MustCompile(` fsuid.*`), ""}, - {regexp.MustCompile(` exe=.*`), ""}, + {regexp.MustCompile(`(peer_|)pid=[0-9]*\s`), " "}, + {regexp.MustCompile(`\x1d`), " "}, } ) @@ -154,18 +154,24 @@ func (aaLogs AppArmorLogs) String() string { // Print order of impression keys := []string{ "profile", "label", // Profile name - "operation", "name", + "operation", "name", "target", "mask", "bus", "path", "interface", "member", // dbus "info", "comm", "laddr", "lport", "faddr", "fport", "family", "sock_type", "protocol", "requested_mask", "denied_mask", "signal", "peer", // "fsuid", "ouid", "FSUID", "OUID", } + // Key to not print + ignore := []string{ + "fsuid", "ouid", "FSUID", "OUID", "exe", "SAUID", "sauid", "terminal", + "UID", "AUID", "hostname", "addr", + } // Color template to use colors := map[string]string{ "profile": fgBlue, "label": fgBlue, "operation": fgYellow, "name": fgMagenta, + "target": "-> " + fgMagenta, "mask": boldRed, "bus": fgCian + "bus=", "path": "path=" + fgWhite, @@ -178,9 +184,14 @@ func (aaLogs AppArmorLogs) String() string { for _, log := range aaLogs { seen := map[string]bool{"apparmor": true} res += state[log["apparmor"]] + fsuid := log["fsuid"] + ouid := log["ouid"] for _, key := range keys { if log[key] != "" { + if key == "name" && fsuid == ouid && !strings.Contains(log["operation"], "dbus") { + res += colors[key] + " owner" + reset + } if colors[key] != "" { res += " " + colors[key] + toQuote(log[key]) + reset } else { @@ -191,6 +202,9 @@ func (aaLogs AppArmorLogs) String() string { } for key, value := range log { + if slices.Contains(ignore, key) { + continue + } if !seen[key] && value != "" { res += " " + key + "=" + toQuote(value) } diff --git a/pkg/logs/logs_test.go b/pkg/logs/logs_test.go index c96167dc0..a67e7bb21 100644 --- a/pkg/logs/logs_test.go +++ b/pkg/logs/logs_test.go @@ -11,32 +11,61 @@ import ( "testing" ) -var refKmod = AppArmorLogs{ - { - "apparmor": "ALLOWED", - "profile": "kmod", - "operation": "file_inherit", - "comm": "modprobe", - "family": "unix", - "sock_type": "stream", - "protocol": "0", - "requested_mask": "send receive", - }, -} - -var refMan = AppArmorLogs{ - { - "apparmor": "ALLOWED", - "profile": "man", - "operation": "exec", - "name": "/usr/bin/preconv", - "info": "no new privs", - "comm": "man", - "requested_mask": "x", - "denied_mask": "x", - "error": "-1", - }, -} +var ( + refKmod = AppArmorLogs{ + { + "apparmor": "ALLOWED", + "profile": "kmod", + "operation": "file_inherit", + "comm": "modprobe", + "family": "unix", + "sock_type": "stream", + "protocol": "0", + "requested_mask": "send receive", + }, + } + refMan = AppArmorLogs{ + { + "apparmor": "ALLOWED", + "profile": "man", + "operation": "exec", + "name": "/usr/bin/preconv", + "target": "man_groff", + "info": "no new privs", + "comm": "man", + "requested_mask": "x", + "denied_mask": "x", + "error": "-1", + "fsuid": "1000", + "ouid": "0", + "FSUID": "user", + "OUID": "root", + }, + } + refPowerProfiles = AppArmorLogs{ + { + "apparmor": "ALLOWED", + "profile": "", + "label": "power-profiles-daemon", + "operation": "dbus_method_call", + "name": "org.freedesktop.DBus", + "mask": "send", + "bus": "system", + "path": "/org/freedesktop/DBus", + "interface": "org.freedesktop.DBus", + "member": "AddMatch", + "peer_label": "dbus-daemon", + "exe": "/usr/bin/dbus-daemon", + "sauid": "102", + "hostname": "?", + "addr": "?", + "terminal": "?", + "UID": "messagebus", + "AUID": "unset", + "SAUID": "messagebus", + }, + } +) func TestAppArmorEvents(t *testing.T) { tests := []struct { @@ -57,6 +86,8 @@ func TestAppArmorEvents(t *testing.T) { "requested_mask": "wc", "denied_mask": "wc", "parent": "6974", + "fsuid": "30", + "ouid": "30", }, }, }, @@ -73,6 +104,8 @@ func TestAppArmorEvents(t *testing.T) { "requested_mask": "rw", "denied_mask": "rw", "parent": "16001", + "fsuid": "0", + "ouid": "1000", }, }, }, @@ -90,12 +123,14 @@ func TestAppArmorEvents(t *testing.T) { "requested_mask": "r", "denied_mask": "r", "error": "-13", + "fsuid": "1002", + "ouid": "0", }, }, }, { name: "dbus_system", - event: `type=USER_AVC msg=audit(1111111111.111:1111): pid=1780 uid=102 auid=4294967295 ses=4294967295 subj=? msg='apparmor="ALLOWED" operation="dbus_method_call" bus="system" path="/org/freedesktop/PolicyKit1/Authority" interface="org.freedesktop.PolicyKit1.Authority" member="CheckAuthorization" mask="send" name="org.freedesktop.PolicyKit1" pid=1794 label="snapd" peer_pid=1790 peer_label="polkitd" exe="/usr/bin/dbus-daemon" sauid=102 hostname=? addr=? terminal=?'UID="messagebus" AUID="unset" SAUID="messagebus"`, + event: `type=USER_AVC msg=audit(1111111111.111:1111): pid=1780 uid=102 auid=4294967295 ses=4294967295 subj=? msg='apparmor="ALLOWED" operation="dbus_method_call" bus="system" path="/org/freedesktop/PolicyKit1/Authority" interface="org.freedesktop.PolicyKit1.Authority" member="CheckAuthorization" mask="send" name="org.freedesktop.PolicyKit1" pid=1794 label="snapd" peer_pid=1790 peer_label="polkitd" exe="/usr/bin/dbus-daemon" sauid=102 hostname=? addr=? terminal=? UID="messagebus" AUID="unset" SAUID="messagebus"`, want: AppArmorLogs{ { "apparmor": "ALLOWED", @@ -109,6 +144,14 @@ func TestAppArmorEvents(t *testing.T) { "interface": "org.freedesktop.PolicyKit1.Authority", "member": "CheckAuthorization", "peer_label": "polkitd", + "exe": "/usr/bin/dbus-daemon", + "sauid": "102", + "hostname": "?", + "addr": "?", + "terminal": "?", + "UID": "messagebus", + "AUID": "unset", + "SAUID": "messagebus", }, }, }, @@ -156,6 +199,10 @@ func TestNewApparmorLogs(t *testing.T) { "comm": "dnsmasq", "requested_mask": "r", "denied_mask": "r", + "fsuid": "0", + "ouid": "0", + "FSUID": "root", + "OUID": "root", }, { "apparmor": "DENIED", @@ -165,6 +212,10 @@ func TestNewApparmorLogs(t *testing.T) { "comm": "dnsmasq", "requested_mask": "r", "denied_mask": "r", + "fsuid": "0", + "ouid": "0", + "FSUID": "root", + "OUID": "root", }, { "apparmor": "DENIED", @@ -174,6 +225,10 @@ func TestNewApparmorLogs(t *testing.T) { "comm": "dnsmasq", "requested_mask": "r", "denied_mask": "r", + "fsuid": "0", + "ouid": "0", + "FSUID": "root", + "OUID": "root", }, }, }, @@ -190,21 +245,7 @@ func TestNewApparmorLogs(t *testing.T) { { name: "power-profiles-daemon", path: "../../tests/audit.log", - want: AppArmorLogs{ - { - "apparmor": "ALLOWED", - "profile": "", - "label": "power-profiles-daemon", - "operation": "dbus_method_call", - "name": "org.freedesktop.DBus", - "mask": "send", - "bus": "system", - "path": "/org/freedesktop/DBus", - "interface": "org.freedesktop.DBus", - "member": "AddMatch", - "peer_label": "dbus-daemon", - }, - }, + want: refPowerProfiles, }, } for _, tt := range tests { @@ -231,26 +272,12 @@ func TestAppArmorLogs_String(t *testing.T) { { name: "man", aaLogs: refMan, - want: "\033[1;32mALLOWED\033[0m \033[34mman\033[0m \033[33mexec\033[0m \033[35m/usr/bin/preconv\033[0m info=\"no new privs\" comm=man requested_mask=\033[1;31mx\033[0m denied_mask=\033[1;31mx\033[0m error=-1\n", + want: "\033[1;32mALLOWED\033[0m \033[34mman\033[0m \033[33mexec\033[0m \033[35m/usr/bin/preconv\033[0m -> \033[35mman_groff\033[0m info=\"no new privs\" comm=man requested_mask=\033[1;31mx\033[0m denied_mask=\033[1;31mx\033[0m error=-1\n", }, { - name: "power-profiles-daemon", - aaLogs: AppArmorLogs{ - { - "apparmor": "ALLOWED", - "profile": "", - "label": "power-profiles-daemon", - "operation": "dbus_method_call", - "name": "org.freedesktop.DBus", - "mask": "send", - "bus": "system", - "path": "/org/freedesktop/DBus", - "interface": "org.freedesktop.DBus", - "member": "AddMatch", - "peer_label": "dbus-daemon", - }, - }, - want: "\033[1;32mALLOWED\033[0m \033[34mpower-profiles-daemon\033[0m \033[33mdbus_method_call\033[0m \033[35morg.freedesktop.DBus\033[0m \033[1;31msend\033[0m \033[36mbus=system\033[0m path=\033[37m/org/freedesktop/DBus\033[0m interface=\033[37morg.freedesktop.DBus\033[0m member=\033[32mAddMatch\033[0m peer_label=dbus-daemon\n", + name: "power-profiles-daemon", + aaLogs: refPowerProfiles, + want: "\033[1;32mALLOWED\033[0m \033[34mpower-profiles-daemon\033[0m \033[33mdbus_method_call\033[0m \033[35morg.freedesktop.DBus\033[0m \033[1;31msend\033[0m \033[36mbus=system\033[0m path=\033[37m/org/freedesktop/DBus\033[0m interface=\033[37morg.freedesktop.DBus\033[0m member=\033[32mAddMatch\033[0m peer_label=dbus-daemon\n", }, } for _, tt := range tests { diff --git a/tests/audit.log b/tests/audit.log index 09ae74210..b8b6fd5b2 100644 --- a/tests/audit.log +++ b/tests/audit.log @@ -25,12 +25,13 @@ type=AVC msg=audit(1111111111.111:1111): apparmor="DENIED" operation="file_inher type=AVC msg=audit(1111111111.111:1111): apparmor="ALLOWED" operation="open" profile="fusermount" name="/run/user/1000/doc/" pid=8703 comm="fusermount" requested_mask="r" denied_mask="r" fsuid=0 ouid=1000FSUID="root" OUID="user" type=AVC msg=audit(1111111111.111:1111): apparmor="DENIED" operation="open" profile="chrome-gnome-shell" name="/home/user/.netrc" pid=9119 comm="chrome-gnome-sh" requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000FSUID="user" OUID="user" type=BPF msg=audit(1111111111.111:1111): prog-id=26 op=LOAD -type=AVC msg=audit(1111111111.111:1111): apparmor="ALLOWED" operation="exec" info="no new privs" error=-1 profile="man" name="/usr/bin/preconv" pid=60755 comm="man" requested_mask="x" denied_mask="x" fsuid=1000 ouid=0 target="man_groff"FSUID="user" OUID="root" +type=AVC msg=audit(1111111111.111:1111): apparmor="ALLOWED" operation="exec" info="no new privs" error=-1 profile="man" name="/usr/bin/preconv" pid=60755 comm="man" requested_mask="x" denied_mask="x" fsuid=1000 ouid=0 target="man_groff" FSUID="user" OUID="root" type=USER_AVC msg=audit(1111111111.111:1111): pid=1648 uid=102 auid=4294967295 ses=4294967295 subj=? msg='apparmor="ALLOWED" operation="dbus_method_call" bus="system" path="/org/freedesktop/DBus" interface="org.freedesktop.DBus" member="AddMatch" name=":1.3" mask="receive" label="dbus-daemon" peer_pid=1667 peer_label="power-profiles-daemon" exe="/usr/bin/dbus-daemon" sauid=102 hostname=? addr=? terminal=?'UID="messagebus" AUID="unset" SAUID="messagebus" type=AVC msg=audit(1111111111.111:1111): apparmor="ALLOWED" operation="file_perm" parent=16001 profile=666F6F20626172 name="/home/foo/.bash_history" pid=17011 comm="bash" requested_mask="rw" denied_mask="rw" fsuid=0 ouid=1000 -type=USER_AVC msg=audit(1111111111.111:1111): pid=1648 uid=102 auid=4294967295 ses=4294967295 subj=? msg='apparmor="ALLOWED" operation="dbus_method_call" bus="system" path="/org/freedesktop/DBus" interface="org.freedesktop.DBus" member="AddMatch" mask="send" name="org.freedesktop.DBus" pid=1667 label="power-profiles-daemon" peer_label="dbus-daemon" exe="/usr/bin/dbus-daemon" sauid=102 hostname=? addr=? terminal=?'UID="messagebus" AUID="unset" SAUID="messagebus" +type=USER_AVC msg=audit(1111111111.111:1111): pid=1648 uid=102 auid=4294967295 ses=4294967295 subj=? msg='apparmor="ALLOWED" operation="dbus_method_call" bus="system" path="/org/freedesktop/DBus" interface="org.freedesktop.DBus" member="AddMatch" mask="send" name="org.freedesktop.DBus" pid=1667 label="power-profiles-daemon" peer_label="dbus-daemon" exe="/usr/bin/dbus-daemon" sauid=102 hostname=? addr=? terminal=? UID="messagebus" AUID="unset" SAUID="messagebus" type=USER_AVC msg=audit(1111111111.111:1111): pid=1648 uid=102 auid=4294967295 ses=4294967295 subj=? msg='apparmor="ALLOWED" operation="dbus_method_call" bus="system" path="/org/freedesktop/DBus" interface="org.freedesktop.DBus" member="AddMatch" name=":1.4" mask="receive" label="dbus-daemon" peer_pid=1 peer_label="unconfined" exe="/usr/bin/dbus-daemon" sauid=102 hostname=? addr=? terminal=?'UID="messagebus" AUID="unset" SAUID="messagebus" type=AVC msg=audit(1111111111.111:1111): apparmor="ALLOWED" operation="bind" profile="gnome-shell" pid=2027 comm="gnome-shell" family="unix" sock_type="stream" protocol=0 requested_mask="bind" denied_mask="bind" addr="@/tmp/.X11-unix/X1" type=AVC msg=audit(1111111111.111:1111): apparmor="ALLOWED" operation="file_perm" profile="gnome-session-binary" pid=1995 comm="gnome-session-b" family="unix" sock_type="stream" protocol=0 requested_mask="send receive" denied_mask="send receive" addr="@/tmp/.ICE-unix/1995" peer_addr=none peer="gnome-shell" Sep 6 11:23:47 xubuntu-lts kernel: [ 31.024982] audit: type=1107 audit(1111111111.111:1111): pid=1567 uid=102 auid=4294967295 ses=4294967295 subj=? msg='apparmor="ALLOWED" operation="dbus_method_call" bus="system" path="/org/freedesktop/Accounts/User1000" interface="org.freedesktop.DBus.Properties" member="GetAll" mask="send" name="org.freedesktop.Accounts" pid=1693 label="lightdm" peer_pid=1559 peer_label="accounts-daemon" Sep 6 11:26:12 xubuntu-lts kernel: [ 175.272924] audit: type=1107 audit(1111111111.111:1111): pid=1567 uid=102 auid=4294967295 ses=4294967295 subj=? msg='apparmor="ALLOWED" operation="dbus_signal" bus="system" path="/org/freedesktop/Accounts/User1000" interface="org.freedesktop.Accounts.User" member="Changed" name=":1.6" mask="receive" pid=1693 label="lightdm" peer_pid=1559 peer_label="accounts-daemon" +type=AVC msg=audit(1111111111.111:1111): apparmor="ALLOWED" operation="link" class="file" profile="akonadi_maildispatcher_agent" name="/home/bob/.config/akonadi/agent_config_akonadi_maildispatcher_agent.CmJRGE" pid=19277 comm="akonadi_maildis" requested_mask="k" denied_mask="k" fsuid=1000 ouid=1000 target="/home/bob/.config/akonadi/#3029891" FSUID="user" OUID="user"