Extended privilege policy can limit attacker access to a system when an attack on an application is successful. An extended policy rule limits the scope of the effect of a privilege assignment to just the resource that is in the rule. Extended policy rules are expressed by enclosing the privileges between curly braces, followed by a colon and the associated resource. For more discussion, see Expanding a User or Role's Privileges. For examples of the syntax, see the ppriv(1) and privileges(5) man pages.
Both administrators and regular users can lock down resources by using extended privileges. Administrators can create extended privilege rules for users, ports, and applications. Regular users can use the command line or write scripts that use the ppriv -r command to prevent applications from writing files outside of user-specified directories.
Limit the access available to a malicious user who enters by a port – How to Apply Extended Privilege Policy to a Port
Run a database as a non-root daemon – How to Lock Down the MySQL Service
Run the Apache HTTP Server as a non-root daemon – How to Assign Specific Privileges to the Apache HTTP Server
Verify that the Apache HTTP Server is running with privileges – How to Determine Which Privileges the Apache HTTP Server Is Using
Prevent Firefox from writing to directories on your system – Example 39, Running a Browser in a Protected Environment
Limit your applications to specific directories on your system – Example 40, Protecting Directories on Your System From Application Processes
The service for the Network Time Protocol (NTP) uses the privileged port 123 for udp traffic. Privileges are required for this service to run. This example procedure modifies the service manifest to protect other ports from being accessed by a malicious user who might gain the privileges that are assigned to this port.
Before You Begin
You must assume the root role. For more information, see Using Your Assigned Administrative Rights.
From the following /lib/svc/manifest/network/ntp.xml start method entry, the net_privaddr, proc_lock_memory, and sys_time privileges could be used on other processes:
privileges='basic,!file_link_any,!proc_info,!proc_session,net_privaddr, proc_lock_memory,sys_time'
The removed privileges specified by !file_link_any,!proc_info,!proc_session prevent the service from signaling or observing any other processes, and from creating hard links as a way of renaming files. That is, the process that is started by the service is only able to bind to NTP's port 123, not to any of the other privileged ports.
If a hacker could exploit the service to start another process, that process would be similarly limited.
# svccfg -s ntp editprop -a
The extended privilege policy removes all privileges from this service except the specified privileges plus the basic privileges that are not specified. Therefore, the set of over eighty potentially exploitable privileges is reduced to less than eight.
# svcadm restart ntp
# svcprop -s ntp | grep privileges start/privileges astring basic,!file_link_any,!proc_info,!proc_session, {net_privaddr}:123/udp,proc_lock_memory,sys_time restart/privileges astring basic,!file_link_any,!proc_info,!proc_session, {net_privaddr}:123/udp,proc_lock_memory,sys_time
At installation, the MySQL database is configured to run with the full privileges of root over an unprotected port. In this task, you assign extended privilege policy to the MySQL service in a rights profile. After the rights profile becomes the exec method of the service, MySQL runs over a protected port as the user mysql with limited database access by non-MySQL processes.
Before You Begin
The initial user can install the package. The remaining steps must be performed by the root role. For more information, see Using Your Assigned Administrative Rights.
# pkg search basename:mysql ... basename ... pkg:/database/mysql-55@version # pfexec pkg install mysql-55
# svcs mysql STATE STIME FMRI disabled May_15 svc:/application/database/mysql:version_55
The service manifest for this service specifies that the execution method is a shell script wrapper, /lib/svc/method/mysql_55.
# svcprop -s mysql | grep manifest ... astring /lib/svc/manifest/application/database/mysql_55.xml # grep exec= /lib/svc/manifest/application/database/mysql_55.xml exec='/lib/svc/method/mysql_55 start' exec='/lib/svc/method/mysql_55 stop'
Use the /lib/svc/method/mysql_55 wrapper for the command in the profile.
$ su - Password: xxxxxxxx # profiles -p "MySQL Service" MySQL Service> set desc="Locking down the MySQL Service" MySQL Service> add cmd=/lib/svc/method/mysql_55 MySQL Service:mysql_55> set privs=basic MySQL Service:mysql_55> add privs={net_privaddr}:3306/tcp MySQL Service:mysql_55> add privs={file_write}:/var/mysql/5.5/data/* MySQL Service:mysql_55> add privs={file_write}:/tmp/mysql.sock MySQL Service:mysql_55> add privs={file_write}:/var/tmp/ib* MySQL Service:mysql_55> end MySQL Service> set uid=mysql MySQL Service> set gid=mysql MySQL Service> exit
The file_write privilege is a basic privilege granted by default to all processes. By explicitly enumerating the writable paths, write access is restricted to just those paths. This constraint applies to the specified executable and its child processes.
# ipadm set-prop -p extra_priv_ports+=3306 tcp # ipadm show-prop -p extra_priv_ports tcp PROTO PROPERTY PERM CURRENT PERSISTENT DEFAULT POSSIBLE tcp extra_priv_ports rw 2049,4045, 3306 2049,4045 1-65535 3306
The net_privaddr privilege is required to bind to a privileged port. In the case of MySQL, binding to the default port number, 3306, does not normally require this privilege.
# svccfg -s mysql:version_55 ...version_55> setprop method_context/profile="MySQL Service" ...version_55> setprop method_context/use_profile=true ...version_55> refresh ...version_55> exit
The last component of the FMRI, mysql:version_55, is sufficient to uniquely specify the service.
# svcadm enable mysql:version_55
# ppriv $(pgrep mysql) 103697: /usr/mysql/5.5/bin/mysqld --basedir=/usr/mysql/5.5 --datadir=/var/mysql/5.5/data flags = PRIV_XPOLICY Extended policies: {net_privaddr}:3306/tcp {file_write}:/var/mysql/5.5/data/* {file_write}:/tmp/mysql.sock {file_write}:/var/tmp/ib* E: basic,!file_write I: basic,!file_write P: basic,!file_write L: all 103609: /bin/sh /usr/mysql/5.5/bin/mysqld_safe --user=mysql --datadir=/var/mysql/5.5/data flags = PRIV_XPOLICY Extended policies: {net_privaddr}:3306/tcp {file_write}:/var/mysql/5.5/data/* {file_write}:/tmp/mysql.sock {file_write}:/var/tmp/ib* E: basic,!file_write I: basic,!file_write P: basic,!file_write L: all
This procedure locks down the web server daemon by assigning to it only the privileges it needs. The web server can only bind to port 80, and can only write to files that the webservd daemon owns. No apache22 service processes run as root.
Before You Begin
You must assume the root role. For more information, see Using Your Assigned Administrative Rights.
# profiles -p "Apache2" profiles:Apache2> set desc="Apache HTTP Server Extended Privilege" profiles:Apache2> add cmd=/lib/svc/method/http-apache22 profiles:Apache2:http-apache22> add privs={net_privaddr}:80/tcp ...http-apache22> add privs={zone}:/system/volatile/apache2 ...http-apache22> add privs={zone}:/var/apache2/2.2/logs/* ...http-apache22> add privs={zone}:/var/user ...http-apache22> add privs={file_write}:/var/user/webserv* ...http-apache22> add privs={file_write}:/tmp/* ...http-apache22> add privs={file_write}:/system/volatile/apache* ...http-apache22> add privs={file_write}:/proc/* ...http-apache22> add privs=basic,proc_priocntl ...http-apache22> set uid=webservd ...http-apache22> set gid=webservd ...http-apache22> end ---Apache2> exit
# profiles -p "Apache2" profiles:Apache2> add privs={net_privaddr}:443/tcp profiles:Apache2> add privs={net_privaddr}:8443/tcp profiles:Apache2:http-apache22> end
The SSL kernel proxy procedure is described in How to Configure an Apache 2.2 Web Server to Use the SSL Kernel Proxy in Securing the Network in Oracle Solaris 11.3.
# svccfg -s apache22 svc:/network/http:Apache2> listprop start/exec start/exec astring "/lib/svc/method/http-apache22 start" ... svc:/network/http:Apache2> setprop start/profile="Apache2" svc:/network/http:Apache2> setprop start/use_profile=true svc:/network/http:Apache2> refresh svc:/network/http:Apache2> exit
When the apache22 service is enabled, the Apache2 profile will be used.
# svcadm enable apache22
Open a browser and type localhost in the Firefox URL field.
Next Steps
To verify that the privileges are applied correctly, continue with How to Determine Which Privileges the Apache HTTP Server Is Using.
In this task, you determine which privileges the web server is using by creating a debug version of the Apache2 rights profile.
Before You Begin
You have completed How to Assign Specific Privileges to the Apache HTTP Server. The apache22 service is disabled. You are in the root role.
Debugging a command is simpler than debugging an SMF service. The apachectl command starts the Apache service interactively.
# profiles -p "Apache2" profiles:Apache2> set name="Apache-debug" profiles:Apache-debug> sel <Tab><Tab> profiles:Apache-debug:http-apache22> set id=/usr/apache2/2.2/bin/apachectl profiles:Apache-debug:apachectl> end profiles:Apache-debug> exit
For more information, see the apachectl(8) man page.
# usermod -K profiles+=Apache-debug webservd
# su - webservd
# id uid=80(webservd) gid=80(webservd)
Do not use SMF directly. Use the command in the Apache-debug rights profile.
$ pfbash # ppriv -De /usr/apache2/2.2/bin/apachectl start
# ppriv $(pgrep httpd|head -1) 2999: httpd flags = PRIV_DEBUG|PRIV_XPOLICY|PRIV_EXEC 5 Extended policies: 6 {net_privaddr}:80/tcp 7 {zone}:/system/volatile/apache2 8 {zone}:/var/apache2/2.2/logs/* 9 {zone}:/var/user 10 {file_write}:/var/user/webserv* 11 {file_write}:/tmp/* 12 {file_write}:/system/volatile/apache* 13 {file_write}:/proc/* 14 E: basic,!file_write,!proc_info,proc_priocntl 15 I: basic,!file_write,!proc_info,proc_priocntl 16 P: basic,!file_write,!proc_info,proc_priocntl 17 L: all