BBS水木清华站∶精华区

发信人: lenx (冷·枫), 信区: Linux 
标  题: [安全] Non-executable user stack and symlink fix 
发信站: BBS 水木清华站 (Mon Nov 24 22:01:15 1997) 
 
Linux目前安全的最佳方案, 对stack overflow和symlink的攻击都有了相当好的防范 
 
ftp://ftp.sepc.ac.cn/pub/linux/collect/system/kernel/linux-stack-symlink.tgz 
 
(sepc只对166.111/159.226/162.105开放) 
 
 
    Non-executable user stack area and symlink fix -- Linux kernel patch 
   ---------------------------------------------------------------------- 
 
========== 
 Overview 
========== 
 
This patch is intended to add protection against two classes of security 
holes: buffer overflows and symlinks in /tmp. 
 
Most buffer overflow exploits are based on overwriting a function's return 
address on the stack to point to some arbitrary code, which is also put 
onto the stack. If the stack area is non-executable, buffer overflow 
vulnerabilities become harder to exploit. 
 
Another way to exploit a buffer overflow is to point the return address to 
a function in libc, usually system(). This patch also changes the default 
address that shared libraries are mmap()ed at to make it always contain a 
zero byte. This makes it impossible to specify any more data (parameters 
to the function, or more copies of the return address when filling with a 
pattern) in an exploit that has to do with ASCIIZ strings (this is the 
case for most overflow vulnerabilities). 
 
However, note that this patch is by no means a complete solution, it just 
adds an extra layer of security. Some buffer overflow vulnerabilities will 
still remain exploitable a more complicated way. The reason for using such 
a patch is to protect against some of the buffer overflow vulnerabilities 
that are yet unknown. 
 
In this version of my patch I also added a symlink security fix, originally 
by Andrew Tridgell. I changed it to prevent from using hard links too, by 
simply not allowing non-root users to create hard links to files they don't 
own, in +t directories. This seems to be the desired behavior anyway, since 
otherwise users couldn't remove such links they just created. I also added 
exploit attempt logging, this code is shared with the non-executable stack 
stuff, and was the reason to make it a single patch instead of two separate 
ones. You can enable them separately anyway. 
 
================ 
 How to install 
================ 
 
Apply the patch. Enable prompting for experimental code in your kernel 
configuration, enable the patch itself (in General setup section). Read 
help for the suboptions, and configure them. Also, enable the symlink fix 
(in Filesystems section). Build the kernel and reboot. 
 
You may also want to add the following line to your /etc/syslog.conf to 
log [security] alerts separately: 
 
kern.alert                                      /var/log/alert 
 
Additionally, you may do something like this (assuming the log file will 
be empty most of the time): 
 
 /var/log/alert 
chown root.staff /var/log/alert 
chmod 640 /var/log/alert 
echo "more /var/log/alert" >> ~your_usual_non-root_account/.bash_profile 
chattr +a /var/log/alert 
 
[ The last command doesn't do much -- there're too many ways to get around 
securelevel in Linux right now: loading a kernel module, writing to the 
hard disk device, using iopl() and writing to the hard disk via ports... 
This can't be done over NFS however... ] 
 
Ensure that the patch is working correctly, use stacktest.c for that -- 
running './stacktest -e' should segfault, and a message about possible 
buffer overflow exploit attempt should get logged to /var/log/alert (with 
syslogd configuration described above, and if you have logging enabled). 
If you enabled GCC trampolines autodetection, try running './stacktest -t', 
it should succeed. 
 
Also, check the address libc is mmap()ed at, its MSB should be zero instead 
of 0x40 like it was before. Use a command like this: 
 
strace /bin/ls 2>&1 | grep mmap\[^\|\]\*\|PROT_EXEC | sed s/\[^=\]\*=// 
 
If you enabled the symlink fix you can also try to create a symlink in /tmp 
(as a non-root user) pointing to a file that user has no read access to, 
then switch to some other user that has the read access (for example, root) 
and try to read the file via the link (like, cat /tmp/link). This should 
fail, and a message should get logged (if enabled). Everything is similar 
for write access, and for symlinks to files that don't exist. Now, you can 
try to create a hard link in /tmp as a non-root user to a file that user 
doesn't own. This should also fail. 
 
======== 
 F.A.Q. 
======== 
 
Q: Will GCC-compiled programs that use trampolines work with the patch? 
A: Yes, read help for the 'Autodetect GCC trampolines' configuration option. 
 
Q: How do you differ a trampoline call from an exploit attempt? 
A: Since most buffer overflow exploits overwrite the return address, the 
instruction to pass control to the stack has to be a RET. With trampoline 
calls the instruction is a CALL. However, in some cases such trampoline 
autodetection can be fooled by RET'ing to a CALL instruction and making 
this CALL pass control onto the stack (in reality, this also requires a 
register to be set to the address). Again, read help for the 'Autodetect 
GCC trampolines' configuration option. 
 
Q: What is chstk.c for? 
A: The patch adds an extra flag to ELF and a.out headers, which controls 
whether the program will be allowed to execute code on the stack or not, 
and chstk.c is what you should use to manage the flag. You might find it 
useful if you choose to disable the GCC trampolines autodetection. BTW, 
setting the flag also restores the original address shared libraries are 
mmap()ed at, just in case some program depends on that. 
 
Q: Why did you modify signal handler return code? 
A: Originally the kernel put some code onto the stack to return from signal 
handlers. Now signal handler returns are done via the GPF handler instead 
(an invalid magic return address is put on the stack). 
 
Q: What to do if a program needs to follow a symlink in a +t directory for 
its normal operation (without introducing a security hole)? 
A: Usually such a link needs to be created only once, so create it as root. 
Such links are followed even when the patch is enabled. 
 
Q: What will happen if someone does: 
ln -s /etc/passwd ~/link 
ln -s ~/link /tmp/link 
and the vulnerable program runs as root and writes to /tmp/link? 
A: The patch is not looking at the target of the symlink in /tmp, it only 
checks if the symlink itself is owned by the user that vulnerable program 
is running as, and doesn't follow the link if not (like in this example). 
 
Q: Is there some performance impact of using the patch? 
A: Well, the only thing affected is singal handler returns. I didn't want 
to modify the sigreturn syscall, so there is some extra code to setup its 
stack frame. I don't think this has a noticable effect on the performance: 
saved context checks and other signal handling stuff are taking much more 
time. Also, executing code on the stack was not fast anyway. 
 
Signed, 
Solar Designer <solar@false.com> 
 
 
 
-- 
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 162.105.118.33] 

BBS水木清华站∶精华区