Мировая общественность всполошилась после заявления "эксперта" FOON о том, что все члены семейства Windows содержат неисправимую Design Error, могущую привести к локальной эскалации
привилегий вплоть до LocalSystem.

http://www.void.ru/content/994
http://www.xakep.ru/post/16039/default.asp

По мнению FOON'а, посылка определенных Windows Messages может привести к выполнению произвольного кода в контексте другого приложения, в том числе сервиса, запущенного с правами LocalSystem, и это является ошибкой класса Design Error, т.к. проблема вызвана неспособностью отличить сообщение, посланное системой, от сообщения, посланного "зловредным" приложением. 

Однако, давайте разберемся. Для начала, НИКАКИЕ Windows Messages НЕ ПРИВОДЯТ к выполнению произвольного кода "сами по себе", в том числе, упомянутый в эксплоите WM_TIMER, который в качестве параметра может принимать адрес любой процедуры.

Проверить это можно с помощью простенькой программы: 

int x(){
printf("Exploited!\n");
}

int main(){
PostMessage(GetActiveWindow(),WM_TIMER,0,(long)&x);
for(;;)
}

Запустив эту программу, мы не увидим сообщения "Exploited". Почему? Потому, что реакция на сообщение WM_TIMER, так же, как и на любые другие Windows Messages, производится из функции DispatchMessage, которой в нашей программе нет.
А вот как может выглядеть программа, реагирующая на WM_TIMER: 

int main(){

MSG msg;

PostMessage(GetActiveWindow(),WM_TIMER,1,(long)&x);

printf("WM_TIMER=%d addr(x)=%x\n",WM_TIMER,(long)&x);

for(;;){
GetMessage(&msg,GetActiveWindow(),0,65535);
printf("got WM=%d wparam=%x 
lparam=%x\n",msg.message,msg.wParam,msg.lParam);
DispatchMessage(&msg);
printf("dispatched\n");

}
}

Запустив ее, мы получим: 

WM_TIMER=275 addr(x)=401005
got WM=275 wparam=1 lparam=401005
Exploited!
dispatched

Первая строка показывает, что сообщение WM_TIMER имеет код 275, а адрес процедуры x() - 401005. Далее видно, что срабатывает функция GetMessage, а затем выводится строка "получено сообщение с кодом 275, первый параметр - 1, второй параметр -
401005". Далее вызывается функция DispatchMessage, и, очевидно, уже из нее происходит вызов x(), нарисовавшей
"Exploited". Совершенно понятно, что нет никаких проблем программно отфильтровать любые "левые" сообщения, например, вот так: 

for(;;){
GetMessage(&msg,GetActiveWindow(),0,65535);
printf("got WM=%d wparam=%x 
lparam=%x\n",msg.message,msg.wParam,msg.lParam);
if((msg.message==WM_TIMER) && (msg.lParam!=USED_TIMER)){
printf("Hehe. Coolhatsking attempt!\n");
continue;
}
DispatchMessage(&msg);
printf("dispatched\n");

}

И вместо "Exploited" мы получим милую фразу "Hehe. Coolhatsking
attempt!"... Является ли это новостью? Нет. Microsoft
документировала это еще 5 лет назад!

Очевидно, что проблема не столько в самой организации Windows Messages, сколько в незнании механизмов ее работы как у авторов некоторых приложений, оказавшихся уязвимыми, так и у некоторых "security
experts".

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии