发信人: 包子 (我是FQ), 信区: Security
标 题: LIDS Trusted Path Execution (TPE)
发信站: 郑大绿城 BBS (Fri Oct 8 01:15:28 2004), 本站(bbs.zzu.edu.cn)
$Id: LIDS-TPE-feature.txt,v 1.3 2004/03/12 05:58:08 purna Exp $
---------------------------------
LIDS Trusted Path Execution (TPE)
---------------------------------
Yusuf Wilajati Purna (ywpurna@users.sourceforge.net)
March 09, 2004
INTRODUCTION
============
A trusted path is known as one of classic protection mechanisms in a security
model. It is in short a mechanism to make sure that a user can access
the trusted software without being compromised by other processes or users,
and to make sure that the software runs correctly as really intended.
Some standards and papers ([1], [2]) give a more formal definition of
the term.
One concept trying to provide a trusted mechanism with the main purpose of
preventing arbitrary users from executing arbitrary code is usually called
Trusted Path Execution, or TPE for short.
There has been a lot of security enhancements or patches for either Linux
or *BSD kernels implementing this mechanism ([3], [4], [5], [6], and [7]).
From these implementations, in general, TPE can be thought to be built
based on the following 3 main components:
- Trusted Path.
-------------
This is a trusted path in the narrow meaning. Usually, a path is
considered trusted if the parent directory is owned by 'root' and
is neither group or world writeable.
- Trusted ACL.
------------
This is a list of trusted users. That is, in addition to 'root',
a user on the list is considered trusted.
- Rule.
-----
This is a policy or rule to decide if an executable can be run
based on the trusted path and trusted ACL info/states.
For example, [7] has the features as follows: a trusted path and a trusted
ACL as are defined above, and the following rules to decide when an
executable can be run:
- Trusted user, trusted path -> the user can run the executable
- Trusted user, untrusted path -> the user can run the executable
- Untrusted user, trusted path -> the user can run the executable
- Untrusted user, untrusted path -> the user cannot run the executable
Thus, in this implementation, theoritically an executable cannot be run,
only when the user is not trusted (i.e., it is not in the trusted ACL) and
the executable is not in the trusted path.
However, in practice, there are still some holes in this implementation.
For example, since protection mechanisms from LD_PRELOAD/LD_LIBRARY_PATH
(library) type attacks and '/lib/ld-linux.so.X <executable_name>' type attacks
are not implemented, an untrusted user does not need a lot of effort in
order to run an untrusted executable (i.e., an executable that is on
an untrusted path) by exploiting these types of attacks.
Based on mostly the same general concepts of TPE above, I have tried to
enhance the current LIDS so that in TPE mode LIDS will only execute
binaries as well as libraries, and even load kernel modules as far
as they are protected.
APPROACH
========
To enhance LIDS with TPE, we can define the 3 components of general TPE
as follows:
- Trusted Path.
--------------
It's not useful if we define the parent directory owned by root
and neither group or world writeable as a trusted path in LIDS
because one of LIDS motivations is to restrict root's privileges.
Instead, we define that binaries/kernel modules/libraries/paths
are considered trusted if they are protected with READONLY mode
access by LIDS at the minimum. That is, the default rules for
them are READONLY at the minimum.
Examples:
- lidsconf -A -o /sbin -j READONLY
-> Executables under /sbin are trusted.
- lidsconf -A -o /lib -j READONLY
-> Libraries under /lib are trusted.
- lidsconf -A -o /lib/modules -j READONLY
-> Modules under /lib/modules are trusted.
- lidsconf -A -o /var/workdir -j READONLY
lidsconf -A -o /sbin/application_a -j READONLY
lidsconf -A -s /sbin/application_a -o /var/workdir -j WRITE
-> Although the protected application_a has WRITE access to
/var/workdir, files under /var/workdir are considered
trusted.
- Trusted ACL.
------------
It's not useful either if we define a list of trusted users
as a trusted ACL. LIDS focuses more on binaries/programs rather
than users runnning the programs. There is already LIDS ACL.
Here, we can define a LIDS ACL as the trusted ACL.
- Rule.
-----
We can define a simple rule as follows: Only trusted binaries
are allowed to run, and only trusted libraries/kernel modules
are allowed to load.
Hey, wait! It seems that we already have a similar mechanism in LIDS.
Yes, it's right. Currently, when we set CONFIG_LIDS_NO_EXEC_UP to Y
when configuring the kernel, LIDS will refuse to execute unprotected programs
before the kernel is sealed (lidsadm -I). Thus, the basic mechanism is already
available in LIDS. Furthermore, if we take a broader view at the LIDS itself,
LIDS is in fact a kind of TPE implementation in a bigger framework.
IMPLEMENTATION
==============
KERNEL SPACE
------------
In kernel space, a basic funtion to check if a path is protected or not is
already available in LIDS. Thus the task is to create functions that include
the basic function and decide where and when we must do the
permission checking.
The TPE enhancement is implemented in the following 3 functions:
- lids_exec_tpe_permission(brpm)
------------------------------
This is the function to check if the binary is protected or not.
- lids_mmap_tpe_permission(file, protection)
------------------------------------------
This function checks if the library is protected or not.
- lids_module_tpe_permission(module)
----------------------------------
This one is used to check if the module is protected or not
before loading the module.
Places where these functions should be called are mostly derived from
LSM hooks ([8]).
For lids_exec_tpe_permission(brpm), we can place a hook to call the function
in fs/exec.c:do_exec(). The basic algorithm is as follows:
---------------------------------------------------------------------
lids_exec_tpe_permission(bprm)
{
int error = 0
if (!lids_check_base(bprm->file->dentry, LIDS_APPEND))
error = -EACCES;
return error;
}
---------------------------------------------------------------------
Note that this is not the real code. Think of it as pseudo code.
It simply checks if the dentry of the file is protected or not.
If it is not protected, the function simply return an error with
-EACCES as the error code.
Since most of libraries are loaded by using mmap(),
we can place a hook to call the function to check a library in
mm/mmap.c:do_mmap_pgoff(). The following shows a basic algorithm of
lids_mmap_tpe_permission():
---------------------------------------------------------------------
lids_mmap_tpe_permission(file, protection)
{
int error = 0;
if (!file)
return 0;
if (!(protection & PROT_EXEC))
return 0;
if (!lids_check_base(file->dentry, LIDS_APPEND))
error = -EPERM;
return error;
}
---------------------------------------------------------------------
It only checks the file with PROT_EXEC as the memory protection attribute, that
really exists on the file system. If this file is not protected
the function simply returns an error with -EPERM as the error code.
To check if a module is protected or not we can make use of symbols information
in the module. We use the symbols information to derive the path of
the module. A hook to call this function is then can be placed in
kernel/module.c:sys_init_module(). The basic algoritm of the function
is as follows:
---------------------------------------------------------------------
lids_module_tpe_permission(module)
{
int error = 0;
modpath = get_module_path(module);
if (!lids_check_base(modpath->dentry, LIDS_APPEND))
error = -EPERM;
return error;
}
---------------------------------------------------------------------
After getting the path info of the module from the symbols, as the
other two previous functions, lids_module_tpe_permission() checks if the path
is protected or not. It simply returns -EPERM if the path is not protected.
Those are the 3 main functions composing the basic checking mechanism of
LIDS TPE. This mechanism itself is introduced into LIDS as an option that
can be controlled using a LIDS kernel configuration parameter.
We use CONFIG_LIDS_TPE as the parameter. Setting CONFIG_LIDS_TPE to 'Y' when
configuring the kernel for compilation enables the LIDS TPE feature in
the kernel.
USER SPACE
----------
Similar to ACL_DISCOVERY mode, the 'TPE mode' term is used to describe
the state of LIDS during the operation.
To easily control this mode a new flag is added into lidstools: the TPE flag.
Its status can be used to check if the system in TPE mode or not.
We can also use this flag to switch TPE mode to ON and OFF in the system as
follows, respectively:
# lidsadm -S -- +TPE /* This will switch on TPE mode */
# lidsadm -S -- -TPE /* This will switch off TPE mode */
We can also switch on the TPE mode in the same time as sealing the kernel:
# lidsadm -I +TPE
Turning on the ACL_DISCOVERY mode for a while, in the beginning, will help
identify which libraries should be protected when running applications
on TPE mode.
WHAT LIDS TPE CAN DO AND CANNOT DO?
===================================
With the above implementation, then, what LIDS TPE can really do?
It can be simply explained as follows:
- It prevents arbitrary users, including a user with root privilege,
from executing arbitrary executables (unprotected binaries),
including unprotected libraries.
- It prevents arbitrary users, including a user with root privilege,
from loading unprotected kernel modules.
- It protects the system from LD_PRELOAD/LD_LIBRARY_PATH type attacks.
- It protects the system from '/lib/ld-linux.so.X <executable_name>'
type attacks. (*)
(*) Note that for Linux kernels before 2.4.25 and 2.6.0, this protection
mechanism cannot be achieved by simply using 'mount' with the 'noexec'
option. Now, however, we can achieve a protection mechanism from
'/lib/ld-linux.so.X <executable_name>' type attacks in kernels 2.4.25 and
2.6.0. Nevertheless, LIDS TPE is more flexible.
However, no protection mechanism is perfect. And, LIDS TPE is not yet perfect.
Currently, LIDS TPE cannot prevent untrusted scripts from being
executed by trusted intepreters such as sh, perl, etc. Thus, untrusted
scripts can still be run by passing them directly to the corresponding
interpreters. It cannot prevent either arbitrary code execution caused by
buffer overflows vulnerabilities.
CAVEATS
=======
Due to the rule specified in the approach, LIDS TPE can cause trouble for
applications that create temporarily scripts/executables on unprotected
directories (e.g., /tmp) and run them during execution. These kinds of
applications won't run properly.
LIDS TPE will be very annoying if you run LIDS on this mode in your
development environment because you cannot just compile your programs and
test the programs. LIDS TPE is not proper for development environment.
SUMMARY
=======
LIDS TPE can prevent arbitrary users, including a user with root privilege,
from executing arbitrary executables/libraries, as well as from loading
unprotected/untrusted kernel modules.
Although LIDS TPE is not proper for development environment, it can be expected
that it will have some places on production servers since it can raise
the security bar on protecting the integrity of the servers.
For kernel 2.4, integrating LIDS TPE with other security projects
such as, Openwall [9] and PaX [10] projects for example, it can be expected
that we can also prevent arbitrary code execution caused by buffer overflows
vulnerabilities to some degree and new arbitrary code from being introduced
into the task address space.
Finally, please enjoy, give it a try, and report any bugs. :-)
ACKNOWLEDGEMENT
===============
The TPE mechanism presented here is part of a project I have done at
Sony Corp. On behalf of LIDS team, I would like to thank Sony Corp.
for contributing this work for the LIDS community.
AVAILABILITY
============
LIDS TPE has been implemented in LIDS 1.2.0. To control this feature,
you need to use at least, lidstools 0.5.4.
Source code is freely available from http://www.lids.org.
REFERENCES
==========
1. US DoD,
"Trusted Computer System Evaluation Criteria (DOD 5200.28-std)", 1985.
2. Loscocco, Smalley, et al, NSA,
"The Inevitability of Failure: The Flawed Assumption of Security
in Modern Computing Environment", 1998.
http://www.nsa.gov/selinux/papers/inevitability/
3. route|daemon9 <route@infonexus.com>,
"Trusted Path Execution Patch fo Linux 2.0.0+", 1998.
https://www.phrack.com/phrack/52/P52-06
4. Krzysztof G. Baranowski <kgb@manjak.knm.org.pl>,
"Linux Trusted Patch Execution Redux",
https://www.phrack.com/phrack/53/P53-08, 1998.
5. route|Mike Schiffman|daemon9 <route@infonexus.com>,
"Trusted Path/ACL Execution Patches for OpenBSD 2.4-SNAP", 1998.
https://www.phrack.com/phrack/54/P54-06
6. Brian <brian@innu.org>,
"TPE in Stephanie for OpenBSD 3.4", 2003.
http://kaizo.org/mirrors/stephanie/
7. Niki Rahimi <narahimi@us.ibm.com>
"TPE LSM module for Linux 2.5.59 (2.6)", 2003.
http://www-124.ibm.com/developer ... tches/?patch_id=770
8. LSM Developers/Community <linux-security-module@mail.wirex.com>,
"LSM Linux Security Modules".
http://lsm.immunix.org/
9. Solar Designer et al,
"Openwall Project".
http://www.openwall.com/
10. PaX Team,
"aX Project".
http://pax.grsecurity.net/
EOF
--
每天灌一灌,快乐似神仙 :)
※ 来源:.郑大绿城 BBS http://bbs.zzu.edu.cn [FROM: 218.17.77.65] |