Hello everyone,
1st i'm relativley new to selinux, so be patient with me ;). Im
using Fedora 10. I wrote a small c app:
#include <stdio.h>
/* shellcode calls exit_code(2), see man 2 exit_code */
void func(int a, int b, int c) {
int *helper = NULL;
char buf[] = "\x31\xdb\xb3\x02\x31\xc0\xb0\xfc\xcd\x80";
helper = (int *)(&helper+2);
*helper=(int)buf;
}
int main(int c, char **v) {
func(1, 2, 3);
return 0;
}
the shellcode executes exit_group(2) with argument 2 (like
exit_group(2)). Shellcode works as expected. I tested it on several
systems. The shellcode will run in the stack region of the process.
helper = (int *)(&helper+2); will overwrite the saved instrucion
pointer (return address), so the process will continue execution at
address of local variable buf (which is saved on stack). Program was
compiled with: gcc -Xlinker -v -Xlinker execstack -o shellcode_str
shellcode_str.c
Here the commands:
[root@SecLab student]# gcc -Xlinker -z -Xlinker execstack
shellcode_str.c -o shellcode_str
[root@SecLab student]# chcon -t vul_exec_t shellcode_str
[root@SecLab student]# ls -Z shellcode_str
-rwxrwxr-x root root unconfined_u:object_r:vul_exec_t:s0 shellcode_str
(i i did a chcon -t vul_exec_t shellcode_str, so excutable
shellcode_str is labled correctly)
Please note that shellscript will run in domain vul_t.
My te file (vul.te):
## <summary>confines vul</summary>
policy_module(vul,0.0.6)
require { type unconfined_t; }
role unconfined_r types vul_t;
########################################
#
# Declarations
#
type vul_t;
domain_type(vul_t)
# Access to shared libraries
libs_use_ld_so(vul_t)
libs_use_shared_libs(vul_t)
type vul_exec_t;
files_type(vul_exec_t)
domain_entry_file(vul_t, vul_exec_t)
domain_auto_transition_pattern(unconfined_t, vul_exec_t, vul_t);
#auditallow unconfined_t self:process execstack;
#auditallow vul_t self:process execstack;
execstack -q says that the executable has an exectcubale stack:
[root@SecLab student]# execstack -q shellcode_str
X shellcode_str
exucting shellcode_str:
[root@SecLab student]# semodule -R
[root@SecLab student]# ./shellcode_str
[root@SecLab student]# echo $?
2
Return value of 2 indicates that shellcode on the stack has been
executed successfully.
I expected that SELinux will prevent any execution of code on the
stack. But audit.log shows me nothing like this. Here the audit.log,
since last reloead:
type=MAC_POLICY_LOAD msg=audit(1237306463.553:2886): policy loaded
auid=0 ses=133
type=SYSCALL msg=audit(1237306463.553:2886): arch=40000003 syscall=4
success=yes exit=3470910 a0=4 a1=b7bce000 a2=34f63e a3=bf9330f8
items=0 ppid=20508 pid=20509 auid
=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0
ses=133 comm="load_policy" exe="/usr/sbin/load_policy"
subj=unconfined_u:unconfined_r:load_policy_
t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(1237306470.434:2887): avc: denied { read write }
for pid=20511 comm="shellcode_str" name="0" dev=devpts ino=2
scontext=unconfined_u:unconfined_r
:vul_t:s0-s0:c0.c1023
tcontext=unconfined_u:object_r:unconfined_devpts_t:s0 tclass=chr_file
type=AVC msg=audit(1237306470.434:2887): avc: denied { read write }
for pid=20511 comm="shellcode_str" path="/dev/pts/0" dev=devpts ino=2
scontext=unconfined_u:unc
onfined_r:vul_t:s0-s0:c0.c1023
tcontext=unconfined_u:object_r:unconfined_devpts_t:s0 tclass=chr_file
type=AVC msg=audit(1237306470.434:2887): avc: denied { read write }
for pid=20511 comm="shellcode_str" path="/dev/pts/0" dev=devpts ino=2
scontext=unconfined_u:unc
onfined_r:vul_t:s0-s0:c0.c1023
tcontext=unconfined_u:object_r:unconfined_devpts_t:s0 tclass=chr_file
type=AVC msg=audit(1237306470.434:2887): avc: denied { read write }
for pid=20511 comm="shellcode_str" path="/dev/pts/0" dev=devpts ino=2
scontext=unconfined_u:unc
onfined_r:vul_t:s0-s0:c0.c1023
tcontext=unconfined_u:object_r:unconfined_devpts_t:s0 tclass=chr_file
type=SYSCALL msg=audit(1237306470.434:2887): arch=40000003 syscall=11
per=400000 success=yes exit=0 a0=811b480 a1=8121ca8 a2=8110bc0 a3=0
items=0 ppid=6574 pid=20511
auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0
tty=(none) ses=133 comm="shellcode_str" exe="/home/student/
shellcode_str" subj=unconfined_u:unconfined_
r:vul_t:s0-s0:c0.c1023 key=(null)
Does SELinux prevent exectution on the stack? If yes, how can i see
this. It would also be helpful, when i had an example which shows me a
denial of execstack (searching the log gave no results here). Or is
something wrong with my example?
I suppose, i have an wrong understanding adout how SELinux execstack
works. Please help to clarify this.
hope someone can help. tnx in advance.
--
Sebastian Pfaff