Papillon - A Solaris Security Module
|
Definition | Feature |
-DRSRPROC | Restricted Proc |
-DSECSTDFD | Secure STDIO File Descriptors |
-DPPROMISC | Pseudo Promiscuous Flag |
-DMODHIDING | Module Hiding |
Definition | Protection |
-DSYMPROT | Symbolic Link Protection |
-DFIFOPROT | FIFO Protection |
-DHARDPROT | Hardlink Protection |
Note: If you want to compile Papillon for a 64 bit environment (Solaris OE on UltraSparc) you have to use the Sun C Compiler.
You can also modify other variables in the file src/Makefile but in general everything should work on a default Solaris OE installation.
If you are an advanced user and have some experience with kernel modules, you can also edit other files inside the src directory. The following changes can be done in src/papillon.h
The syscall number is defined by SYS_papcomm. If you are sure that this syscall is used on your system, e.g. by a third party software, change the value to another unused system call. You can retrieve a list of all used system calls by examining the system header file /usr/include/sys/systm.h.
You may change the default runtime configuration in src/papillon.c. Read the section about runtime configuration and adjust the values in the pap_config_t config struct.
{ "/usr/bin/foobar", NULL, NULL },
You can only hide files on the same filesystem type where the module itself resides.
Compilation is rather simple and straight-forward
# cd src
# make
# cd ..
Before you permanently install Papillon, it is wise to run some tests. Load the module into the kernel by executing the following command.
# modload ./src/papillon
Run the control tool papctl to check if the module has been loaded successfully and the configuration gets correctly exported.
# ./src/papctl -g
Current configuration of the Papillon module:
- Features
Restricted Proc: on
Pseudo Promiscuous Flag: on
Module Hiding: on
Secure STDIO File Descriptors: on
- Protections
Symlink Protection: deny
Hardlink Protection: deny
Fifo Protection: deny
Now compile the test suite that is part of the Papillon source package.
# cd test
# make
Stay in the test directory. Execute the test.sh shell script. Make sure no one is on your system. Follow the instructions printed by test.sh.
# ./test.sh
This script will check if Papillon is running and all enabled
protections are working.
WARNING: In order to check for possible attacks, it is necessary
to create a vulnerable environment in /tmp/fake. Before
proceeding, check that your machine is running in single
user mode.
Continue (y/n): y
- Checking for a restricted proc... Yes
- Checking for hardlink attack protection... Yes
- Checking for symlink attack protection... Yes
- Checking for fifo attack protection... Yes
- Checking for stdio attack protection... Yes
Done.
You should see something like that in your syslog:
papillon: [ID 404481 kern.warning] WARNING: Denied hardlink to (owner 0:1), process ln /tmp/fake/victim /tmp/fake/attack (pid 3394, uid 60001)
papillon: [ID 642723 kern.warning] WARNING: Denied following symlink (owner 60001:60001), process cat /tmp/fake/attack (pid 3400, uid 0)
papillon: [ID 264911 kern.warning] WARNING: Denied opening fifo (owner 0:1), process ./fifoattack /tmp/fake/victim (pid 3406, uid 60001)
papillon: [ID 637864 kern.warning] WARNING: STDERR closed while executing suid/sgid binary /tmp/fake/suidexec from sh -c /tmp/fake/suidexec /tmp/fake/victim (pid 3415, uid 60001), fake opening STDERR.
papillon: [ID 382957 kern.warning] WARNING: Closing fake opened STDERR.
Make the module visible and unload it. Use modinfo to determin the module id of Papillon and replace ID in the last line with this number.
# cd ..
# modinfo
# ./src/papctl -s m=off
# modunload -i ID
If during the process described above the system panics or any other major problems occur, send a bug report to kr@roqe.org and describe in detail your system, your configuration and the problem that occured. See the section bug reports for more information.
From the src directory you are able to install the module.
# cd src
# make install
# cd ..
These commands will create the following files on your system. (If you have modified some of the path variables in the file src/Makefile , paths may differ)
You can use the following sequence to uninstall the installed files.
# cd src
# make uninstall
# cd ..
Note: Papillon adds a script to the init directory so that the module is loaded at boot time. If you have volume management enabled problems concerning setting the configuration using papctl may occur. Disable the volume management by moving the /etc/rc2.d/S92volmgt script to a save place. If you don't want to disable volume management, read the part about how to cope with the problems in the runtime configuration section.
If all of these files have been installed on your system, you can activate the module by running
# /etc/init.d/papillon start
If you reboot your system, Papillon will automatically be loaded when switching to multiuser level.
If Papillon is loaded, you can use the control tool papctl to toggle features and protections. Below is a list of the commandline and some examples.
Note: If Papillon is loaded and hidden, you are not able to view it on the list of loaded modules generated by modinfo. The control tool papctl is the only way to test if the module is loaded or not in this case.
Usage: | |
papctl -s variable=value [variable=value ...] | |
papctl g | -v | -h |
Options: | ||
-g | get current configuration of the loaded module. | |
-s variable=value ... | set current configuration of the loaded module. | |
-h | print this help. | |
-v | print version information. |
In order to toggle features or protections you have to assign variables the correspoding values. This is the table of all variables, their values and their description.
Variable | Description | Possible values |
r | Restricted Proc | on, off |
p | Pseudo Promiscuous Flag | on, off |
m | Module Hiding | on, off |
i | Secure STDIO File Descriptor | on, off |
s | Symbolic Link Protection | none, warn, deny |
h | Hardlink Protection | none, warn, deny |
f | Fifo Protection | none, warn, deny |
# papctl -s r=off s=warn
# papctl -s r=off p=off m=on i=off s=none h=none f=none
# papctr -s r=on p=on m=on i=on
There is a known problem that causes papctl to fail if the volume managemnt has been loaded after the Papillon module. You can detect this problem if papctl outputs the following error message:
# papctl -s f=none
Error: ##
Configuration blocked. Volmgt running?
You can fix this problem by turning the volume management off, configuring the module, and then reactivating the volume management.
# /etc/init.d/volmgt stop
# papctl -s f=none
# /etc/init.d/volmgt start
This section lists all features and protections that are included in the Papillon module. You should carefully read this section in order to understand how Papillon works and how it achieves an improvement in the system security.
As mentioned in the introduction the so called features of Papillon can be switched on or off either on compilation or even on runtime. See the sections about compilation and runtime configuration how to do both.
By default users on the Solaris OE are able to monitor all active processes (e.g. ps, top). An attacker that has local access to the system might gather useful information by watching system daemons and other users processes. The public information about all running processes also represent a lack of privacy, if a system hosts several independant users.
If the Restricted Proc feature is active, users are only able to view their own processes (processes that are running under their user id uid). There is no possibilty for a user to monitor other users processes since Papillon effects the proc filesystem directly. An attacker which has a local account on the system gains no further information from running commands such as ps or top. Of cause the super-user is able to view all processes.
Papillon extends the access() function of the proc vnode operations provided by prvnodeops to implement the above feature. Unfortunatley the Solaris OE sets the correct permission on the files inside the proc filesystem but does not implement an access() in the proc kernel module. Papillon simply adds this missing access() function.
The Solaris OE 8 and previous versions don't provide a promiscuous mode flag for network cards that is exported to the user. An administrator is not able to monitor a network device for an attacker that is sniffing.
Papillon is able to log all attempts to turn a network device into promiscuous mode that are done using the DPLI Interface. Requests that are performed using a different approach are not detected. Most sniffers use the DLPI Interface.
Papillon intercepts the putmsg() syscall and filters messages that match a DLPI requests (dl_primitive == DL_PROMISCON_REQ and dl_level == DL_PROMISC_PHYS). If a message contains the command for putting a network device into promiscuous mode a warning is send to the syslog. The module is not able to log when a network interface changes back from promiscuous mode to normal operation mode.
In most cases it is not necessary to hide a security module. But if an administrator wants to monitor an exisiting attacker, it might be necessary to make the attacker believe that this system is not protected by any security software.
Papillon is able to remove itself from the list of loaded kernel modules. Papillon denies any access the module's files and hides the module's files from directory listings including the module itself, initscripts and the papctl control program. The super-user is able to view and access all of these files. The list of files to be hidden can be extended at compilation time.
Papillon unlinks itself from the list of loaded modules and relinks itself back in if requested. It also intercepts the vop_lookup() function from his module's file vnode. Access to the file is denied if not the super-user accesses the file. Papillon also intercepts the vop_readdir() function of its parent directory and removes itself from all directory listings by patching the length of previous dirent64 entry using d_len. The entry for Papillon is covered this way.
By default Unix uses the file descriptors 0, 1 and 2 for special purposes.
If an attacker closes one of these file descriptors and executes an insecure program with the suid/sgid bit (permission mode 4000/2000 or u+s/g+s) set, a file descriptor inside the program might be assigned to one of the closed standard file descriptors. In this case information written to STDIN, STDOUT or STDERR might be written to a file. By using this technique an attacker is able to destroy or even modify system files.
Papillon intercepts the execution of all binaries that have the suid/sgid bit set. If the STDIO File Descriptors are closed, Papillon fake opens them during the execution of the suid/sgid program. No suid/sgid program is able to accidently assign a file to the STDIO File Descriptors.
Papillon intercepts the execve() syscall and watches binaries with the suid/sgid bit (Vnode mode S_ISUID or S_ISGID) set. If the Standard File Descriptors are closed, they are faked opened using the kernel allocation routine ualloc(). After executing the original syscall the allocated file descriptors are set free.
Directories with the sticky bit (permission mode +t or 1000) and write-all (Permission mode a+w or 0222) permissions have a specific behaviour: files created in such a directory can only be removed by the file owner or the super-user eventhough write permissions are granted to all users, e.g. /tmp. An attacker can use this feature to drive a symbolic link attack. A symbolic link attack is basicly based on a symbolic link that has the name of a temporary file and links to a file the attacker wants to modify.
Papillon provides a simple symbolic link protection. If a user wants to follow a symbolic link that is within a directory with the sticky bit set, access is denied if all of the following conditions are true:
This protection mechanism especially protects the super-user privileges, an attacker is not able to gain super-user privileges, if the admin executes a binary that creates insecure temporary files.
Papillon watches all calls to the open() and open64() syscalls, if a symbolic link is to be opened that is placed in a directory with the sticky bit (Vnode mode S_ISVTX) set and the above conditions match, the open fails with permission denied (EPERM).
Papillon fixes both problems. If the hard link protection is active users can not create hard links to files they donnot own. The super-user is able to create hard links to all files.
The link() syscall is intercepted and the above protections are implemented. Papillon returns permission denied (EPERM).
A FIFO (e.g. a file created with mkfifo) that is inside a directory with the sticky bit set and write-all permissions can be opened by an attacker using the open flag O_CREAT. In this case all saved content inside the FIFO will be lost.
Papillon restricts access to FIFOs inside directories with the sticky bit set and write-all permissions. Open access to FIFOs is denied if all of the following conditions are true:
Papillon watches all calls to the open() and open64() syscalls, if a FIFO is to be opened with the O_CREAT flag in a directory with the sticky bit (Vnode mode S_ISVTX) set, access is denied if the above conditions match. In this case Papillon returns permission denied (EPERM).
Papillon has been developed in the free time of the author. It is a non-commercial opensource project. Papillon tries to offer a maximum of stability, but due to the reasons mentioned above, it can fail to do so.
Therefore it is essential that users experiencing bugs report them to the author by sending an email to
echo [IMAGE png]$c | mdb unix.0 vmcore.0
You should retrieve a backtrace of the kernel thread that paniced. Include this trace in the email instead of attaching any core file.
The author would like to thank Job de Haas for his ideas, support and the fun during their presentation at HAL2001.
Thanks to Fabian Kroenner for hours of constructive discussion regardings Papillon and its future, there would have been no release without his support.
Konrad Kretschmer was so gentle to read through the complete documentation eleminating at least the obvious misspellings.
The author also would like to thank Philipp Stucke and Skyper who provided some of the test environment.
In the early days of the code Acpizer supplied a reference counter implementation for Papillon. Thanks.