Helsinki Security Meetup: SElinux presentation
Wednesday, August 20. 2014
As promised, here are my presentation slides from Helsinki Security Meetup from August 20th 2014. I did redact my e-mail address to prevent spammers harvesting it. I get enough spam already.
Presentation slides
In PDF-format: 2014HelsinkiSecurityMeetup.pdf
My backdoor C-code
Here it is: backdoor.c
There is no makefile or anything, a simple gcc backdoor.c -o backdoor will do the trick.
Running backdoor
In my demo, there was the insecure directory (run ls -Z to display the file contexts):
-rwxr-xr-x. root root unconfined_u:object_r:httpd_exec_t:s0 backdoor
-rwxr--r--. root root unconfined_u:object_r:admin_home_t:s0 start.backdoor-1.sh
-rwxr--r--. root root unconfined_u:object_r:initrc_exec_t:s0 start.backdoor-2.sh
and one secured directory:
-rwxr-xr-x. root root unconfined_u:object_r:backdoor_exec_t:s0 backdoor.secure
-rwxr--r--. root root unconfined_u:object_r:initrc_exec_t:s0 start.backdoor-3.sh
When running as httpd_t, remember to add the port into Apache allowed ports:
semanage port --add -t http_port_t -p tcp 8282
To (temporarily) change a file context, run a command like:
chcon -t backdoor_t backdoor
To permanantly change the file context,:
semanage fcontext -a -t backdoor_t /a_directory/backdoor
Now, the change will survive a restorecon-call.
What has changed after the presentation
To save system resources with one process, I changed the content of start-backdoor.sh scripts from:
#!/bin/bash
./backdoor.secure
to:
#!/bin/bash
exec ./backdoor.secure
I fixed the bug in fork child code mentioned during the presentation. Now a failing execvp() call does not leak processes. And while at it, I made failing more verbose. It will display the failure both on server and client ends.
During presentation, my backdoor-policy allowed binding the backdoor to any port. I added more security to that, and allow binding only to backdoor_port_t To get the secured backdoor running, you need to remove the TCP/8282 port from Apache, and add it to backdoor:
semanage port --delete -t http_port_t -p tcp 8282
semanage port --add -t backdoor_port_t -p tcp 8282
You can list the allowed ports with a command like:
semanage port -l | fgrep http_port_t
The SElinux backdoor policy files
The package is: backdoor_policy.tar.bz2
Remember to add the package selinux-policy-devel for make to work. Install the newly created policy with following command:
semodule -i backdoor_policy.pp
The new module will survive a system reboot.
What has changed after the presentation
Lot of unnecessary permissions have been dropped. backdoor_t can bind only to backdoor_port_t, not all ports. I also enabled backdoor_t writing to stdout, it helps to see what's going on. It is not typical for daemons to be allowed that, but especially when execvp() fails, it is so much easier to visualize SElinux policy kicking in.
Any comments are welcome!