AppArmor zero-knowledge learning XIV, practical operation and practice (2)

References for the content of this article:

Summary of Linux security module AppArmor - CSDN blog ,

apparmor Homepage, Documentation and Downloads - Application Access Control System - OSCHINA - Chinese Open Source Technology Exchange Community ,

AppArmor · GitBook

AppArmor Configuration (2)_domybest_nsg's Blog-CSDN Blog

Continued from the previous article: AppArmor Zero Knowledge Learning Thirteen, Practice and Practice (1)

The previous article enabled AppArmor, but currently there are no applications with configuration files in the system. This article will add access control rules so that there are applications with configuration files in the system.

2. Add access control rules

1. Write the test routine

First write a test routine, the code is as follows:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>


int main(int argc, char *argv[])
{
        FILE *f;
        int i = 0;
        char ch;

        if(3 == argc)
        {
                f = fopen(argv[1], "w");
                if(!f)
                {
                        fprintf(stderr, "fopen failed with w, error: %s\n", strerror(errno));
                        return 2;
                }
                while(i < strlen(argv[2]))
                {
                        fputc(argv[2][i], f);
                        i++;
                }
                fclose(f);
        }
        else if(argc == 2)
        {
                f = fopen(argv[1], "r");
                if(!f)
                {
                        fprintf(stderr, "fopen failed with r, error: %s\n", strerror(errno));
                        return 2;
                }
                while((ch=fgetc(f)) != EOF)
                        printf(" %c", ch);
                fclose(f);
        }
        else
        {
                printf("Usage:\n");
                printf("\ttest_app file \"string\"\n");
                printf("\ttest_app file\n");
                return 3;
        }

        return 0;
}

Compile and simply test the test routine. As follows:

$ gcc test_app.c -o test_app
$ ls
test_app  test_app.c
$ ./test_app kkk
fopen failed with r, error: No such file or directory

$ ./test_app kkk 1234
$ ./test_app kkk
 1 2 3 4

2. Create a rule

Use genprof to create rules. Proceed as follows:

(1) Go to the directory where the test routine is created

penghao@Ding-Perlis-MP260S48:~/AppArmor$ cd sample_code/
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls
kkk  test_app  test_app.c

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ rm kkk
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls
test_app  test_app.c

(2) Create rules

$ aa-genprof test_app
正在在 /etc/apparmor.d 中更新 AppArmor 配置文件。Writing updated profile for /home/penghao/AppArmor/sample_code/test_app.

ERROR: [Errno 13] Permission denied: '/etc/apparmor.d/tmpdy6clx3q~'

Add sudo in front and execute the above command again:

$ sudo aa-genprof test_app
[sudo] penghao 的密码:正在在 /etc/apparmor.d 中更新 AppArmor 配置文件。Writing updated profile for /home/penghao/AppArmor/sample_code/test_app.
正在将 /home/penghao/AppArmor/sample_code/test_app 设置为投诉模式。
在开始之前,您可能希望检查您希望限制的应用程序的配置文件是否已经存在。有关详细信息,请参考以下维基页面:https://gitlab.com/apparmor/apparmor/wikis/Profiles

分析中: /home/penghao/AppArmor/sample_code/test_app

请启动要在另一个窗口中分析的应用程序,并立即执行其功能。
完成后,选择下面的“扫描”选项,以扫描系统日志中的AppArmor事件。
对于每个 AppArmor 事件,您将有机会选择是应允许还是拒绝访问。
[扫描系统日志以查找 AppArmor 事件(S)] / 完成(F)

Press the 'F' key (no need to enter) to complete the process as shown below:

[扫描系统日志以查找 AppArmor 事件(S)] / 完成(F)
正在设置 /home/penghao/AppArmor/sample_code/test_app 到强制模式
重启 AppArmor 到强制模式
请考虑贡献您的新配置文件!参阅以下 wiki 页面获取更多信息:https://gitlab.com/apparmor/apparmor/wikis/Profiles

已完成为 /home/penghao/AppArmor/sample_code/test_app 生成配置文件。

Check the content under /etc/apparmor.d/:

Compare with previous content:

It can be seen that the biggest change is that there is an additional home.penghao.AppArmor.sample_code.test_app file under /etc/apparmor.d/, and the file name is the absolute path of the file, but changed from '/' to '.' . The content of the file is as follows:

# Last Modified: Wed Apr 19 10:23:02 2023
abi <abi/3.0>,

include <tunables/global>

/home/penghao/AppArmor/sample_code/test_app {
  include <abstractions/base>

  /home/penghao/AppArmor/sample_code/test_app mr,

}

At this time, use the aa-status command mentioned in the previous article查看当前AppArmor的运行状态和具有配置文件的应用程序。命令及结果如下所示:

$ sudo aa-status 
apparmor module is loaded.
1 profiles are loaded.
1 profiles are in enforce mode.
   /home/penghao/AppArmor/sample_code/test_app
0 profiles are in complain mode.
0 profiles are in kill mode.
0 profiles are in unconfined mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
0 processes are in mixed mode.
0 processes are in kill mode.

Compare the results when no rules were set before:

$ sudo apparmor_status 
apparmor module is loaded.

(3) Modify the rules

Modify the /etc/apparmor.d/home.penghao.AppArmor.sample_code.test_app file, and add the following content in the braces of the file:

/home/penghao/AppArmor/sample_code/abcde rwm,
/home/penghao/AppArmor/sample_code/abcd w,
/home/penghao/AppArmor/sample_code/abc r,

The former part is the file name, and the latter part is the permission.

The modified file content is as follows:

# Last Modified: Wed Apr 19 10:23:02 2023
abi <abi/3.0>,

include <tunables/global>

/home/penghao/AppArmor/sample_code/test_app {
  include <abstractions/base>

  /home/penghao/AppArmor/sample_code/test_app mr,
  /home/penghao/AppArmor/sample_code/abcde rwm,
  /home/penghao/AppArmor/sample_code/abcd w,
  /home/penghao/AppArmor/sample_code/abc r,

}

(4) Reload

Execute the following command to reload:

sudo /etc/init.d/apparmor reload

The actual commands and results are as follows:

$ sudo /etc/init.d/apparmor reload
sudo: /etc/init.d/apparmor:找不到命令

In fact, the /etc/init.d/apparmor file is only available under Ubuntu. Since the author's computer system is not Ubuntu, this file does not exist. Copy the /etc/init.d/apparmor file under Ubuntu. The content of the file is as follows:

#!/bin/sh
# ----------------------------------------------------------------------
#    Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
#     NOVELL (All rights reserved)
#    Copyright (c) 2008, 2009 Canonical, Ltd.
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of version 2 of the GNU General Public
#    License published by the Free Software Foundation.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, contact Novell, Inc.
# ----------------------------------------------------------------------
# Authors:
#  Steve Beattie <[email protected]>
#  Kees Cook <[email protected]>
#
# /etc/init.d/apparmor
#
# Note: "Required-Start: $local_fs" implies that the cache may not be available
# yet when /var is on a remote filesystem. The worst consequence this should
# have is slowing down the boot.
#
### BEGIN INIT INFO
# Provides: apparmor
# Required-Start: $local_fs
# Required-Stop: umountfs
# Default-Start: S
# Default-Stop:
# Short-Description: AppArmor initialization
# Description: AppArmor init script. This script loads all AppArmor profiles.
### END INIT INFO

APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions

# Functions needed by rc.apparmor.functions

. /lib/lsb/init-functions

aa_action() {
	STRING=$1
	shift
	$*
	rc=$?
	if [ $rc -eq 0 ] ; then
		aa_log_success_msg $"$STRING "
	else
		aa_log_failure_msg $"$STRING "
	fi
	return $rc
}

aa_log_action_start() {
	log_action_begin_msg $@
}

aa_log_action_end() {
	log_action_end_msg $@
}

aa_log_success_msg() {
	log_success_msg $@
}

aa_log_warning_msg() {
	log_warning_msg $@
}

aa_log_failure_msg() {
	log_failure_msg $@
}

aa_log_skipped_msg() {
	if [ -n "$1" ]; then
		log_warning_msg "${1}: Skipped."
	fi
}

aa_log_daemon_msg() {
	log_daemon_msg $@
}

aa_log_end_msg() {
	log_end_msg $@
}

# Source AppArmor function library
if [ -f "${APPARMOR_FUNCTIONS}" ]; then
	. ${APPARMOR_FUNCTIONS}
else
	aa_log_failure_msg "Unable to find AppArmor initscript functions"
	exit 1
fi

usage() {
    echo "Usage: $0 {start|stop|restart|reload|force-reload|status}"
}

test -x ${PARSER} || exit 0 # by debian policy
# LSM is built-in, so it is either there or not enabled for this boot
test -d /sys/module/apparmor || exit 0

# do not perform start/stop/reload actions when running from liveCD
test -d /rofs/etc/apparmor.d && exit 0

rc=255
case "$1" in
	start)
		if [ -x /usr/bin/systemd-detect-virt ] && \
		   systemd-detect-virt --quiet --container && \
		   ! is_container_with_internal_policy; then
			aa_log_daemon_msg "Not starting AppArmor in container"
			aa_log_end_msg 0
			exit 0
		fi
		apparmor_start
		rc=$?
		;;
	restart|reload|force-reload)
		if [ -x /usr/bin/systemd-detect-virt ] && \
		   systemd-detect-virt --quiet --container && \
		   ! is_container_with_internal_policy; then
			aa_log_daemon_msg "Not starting AppArmor in container"
			aa_log_end_msg 0
			exit 0
		fi
		apparmor_restart
		rc=$?
		;;
	stop)
		aa_log_daemon_msg "Leaving AppArmor profiles loaded"
		cat >&2 <<EOM
No profiles have been unloaded.

Unloading profiles will leave already running processes permanently
unconfined, which can lead to unexpected situations.

To set a process to complain mode, use the command line tool
'aa-complain'. To really tear down all profiles, run 'aa-teardown'."
EOM
		;;
	status)
		apparmor_status
		rc=$?
		;;
	*)
		usage
		rc=1
		;;
	esac
exit $rc

Execute the reload command again, the result is as follows:

$ sudo /etc/init.d/apparmor reload
sudo: /etc/init.d/apparmor:找不到命令

Executable permissions need to be added, the commands and results are as follows:

$ ls /etc/init.d/ -l
总计 12
-rw-rw-r-- 1 root root 3740  4月19日 14:36 apparmor
-rwxr-xr-x 1 root root 1893  2月15日 03:03 fuse
-rw-r--r-- 1 root root 1151  2月15日 00:36 README

$ sudo chmod 755 /etc/init.d/apparmor 
$ 
$ ls /etc/init.d/ -l
总计 12
-rwxr-xr-x 1 root root 3740  4月19日 14:36 apparmor
-rwxr-xr-x 1 root root 1893  2月15日 03:03 fuse
-rw-r--r-- 1 root root 1151  2月15日 00:36 README

Execute again, the result is as follows:

$ sudo /etc/init.d/apparmor reload
/etc/init.d/apparmor:行43: /lib/lsb/init-functions: 没有那个文件或目录

Under Ubuntu, there will be a /lib/lsb/init-functions file, which is not in the author's system. Don't "toss", restart directly, and see if it takes effect after restarting.

3. Test

Enter the directory where the routine is located, and execute the following commands in sequence:

$ pwd
/home/penghao/AppArmor/sample_code
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls
apparmor  test_app  test_app.c
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abc 1abc
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcd 2abcd
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcde 3abcde
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls
abc  abcd  abcde  apparmor  test_app  test_app.c

It can be seen that the three files can be generated normally, and the contents of the three files are checked in turn:

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abc
1abc
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abcd
2abcd
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abcde
3abcde

There are also file contents. Then there is a problem, the above rules:

 /home/penghao/AppArmor/sample_code/abcde rwm,
  /home/penghao/AppArmor/sample_code/abcd w,
  /home/penghao/AppArmor/sample_code/abc r,

It is required that abc can only be read, and abcd can only be written. Why didn't it work? View the system log /var/log/syslog, theoretically you should be able to see information similar to the following:

kernel: [140321.028000] audit(1191433716.584:1578):  type=1502 operation=”inode_create” requested_mask=”w” denied_mask=”w” name=”/home/n1/Desktop/abc” pid=4864 profile=”/home/n1/Desktop/testapp”
kernel: [140362.236000] audit(1191433758.086:1579):  type=1502 operation=”inode_permission” requested_mask=”r” denied_mask=”r” name=”/home/n1/Desktop/abcd” pid=4877 profile=”/home/n1/Desktop/testapp”

Indicates that although the operation is allowed, the abc file is "booked" when it is written, and the abcd file is "booked" when it is read. Because they do not have corresponding permissions in /etc/apparmor.d/home.penghao.AppArmor.sample_code.test_app. But unfortunately, the author did not see similar information under /var/log/syslog. It may be that there are still some problems with the configuration of AppArmor logs.

Regardless of this problem, let's take a look at the situation when it is set to enforce, that is, mandatory mode.

Execute the following command to enter enforcing mode:

$ sudo aa-enforce /etc/apparmor.d/home.penghao.AppArmor.sample_code.test_app 
正在设置 /etc/apparmor.d/home.penghao.AppArmor.sample_code.test_app 到强制模式

At this time, execute the above three commands in sequence again (first delete the previously generated abc, abcd, abcde files), and the results are as follows:

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ rm abc
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ rm abcd
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ rm abcde

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abc 1abc
fopen failed with w, error: Permission denied

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abc
cat: abc: 没有那个文件或目录

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ echo "1abc" > abc
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls abc
abc

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abc
1abc

It can be seen that test_app only has read permission and no write permission for the abc file, and other programs (processes) are not subject to this restriction. 

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcd 2abcd
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls abcd
abcd

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcd
fopen failed with r, error: Permission denied

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abcd
2abcd

It can be seen that test_app only has write permission to the abcd file, but no read permission, and other programs (processes) have no such restrictions.  

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcde 3abcde
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls abcde
abcde

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcde
 3 a b c d e 

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abcde
3abcde

It can be seen that test_app has both write permission and read permission for the abcde file, which is the most normal.

If the permission of the abcde file is set to 0444, let's take a look at the result:

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ chmod 444 abcde

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ echo "1abc" > abcde
bash: abcde: 权限不够

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app 1abc abcde
fopen failed with w, error: Permission denied


penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abcde 
3abcde

penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcde
 3 a b c d e

The above test shows that in the enhanced (enforce) mode, apparmor works normally.

The above is the simplest application. Create a rule file through aa-genprof, and only add the minimum required file read and write permission rules, which
can realize the read and write file control of an unknown program in addition to the file system permission (the file name in the rule file The path can contain wildcards).

To cancel, just delete the corresponding file under /etc/apparmor.d/ and restart the apparmor service.

Guess you like

Origin blog.csdn.net/phmatthaus/article/details/130226606