Зміна LOGIN / PASSWORD під WINNT, Windows 9x/NT, Security & Hack, статті

Оригінальний автор статті – Хернан Очоа
  borisnikolaich

Введення

Частою різновидом атак на Windows NT-системи полягає в спробі отримання імен користувача та контрольних сум з LM / NT-паролів, використовуючи такі програми, як L0phtCrack або tcpdump-smb. Останні використовуються, щоб отримати нелегальний доступ до поділюваних файловим і принтерний ресурсів на атакованих серверах. Щоб зуміти скористатися парами “ім’я користувача / контрольна сума з пароля” замість звичайних пар “ім’я користувача / пароль”, атакуючий повинен скористатися якимось модифікованим SMB-клієнтом. Зазвичай, атакуючими використовується SAMBA (рішення на базі SMB / CIFS для платформ Unix), зважаючи доступності вихідного тексту, що дозволяє без будь-яких ускладнень адаптувати програму для відповідних потреб.

Однак, використання SAMBA в той же час обмежує можливості атаками на колективні ресурси файлів і принтерів. Хоча остання версія SAMBA включає початкову підтримку протоколу MS RPC, вона підтримує далеко не всі можливості, надані стандартними утилітами адміністрування для Windows NT, і, скоріше за все, ніколи не буде. Даний документ роз’яснює, як змінити сертифікат працюючого в Windows NT Server / Workstation користувача, що автоматично дозволяє атакуючому скористатися будь-який “рідний” програмою в Windows NT, яка користується ім’ям користувача і контрольними сумами для перевірки аутентифікації, такими як редактор реєстру (regedit32.exe), менеджер користувачів для доменів (usrmgr.exe), менеджер управління сервісами і тп.

Опис процесу входу користувача в Windows NT і аутентифікації

Існує три основних елементи, задіяних в процесі входу в систему та аутентифікації: logon-процеси, процес сервера LSA, і аутентифікаційні пакети.

LSA довантажує ці бібліотеки в момент завантаження системи, прочитавши записи в ключі реєстру:
\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa under
AuthenticationPackages

Logon-процеси фіксують спроби входу і посилають дані сертифіката користувача в LSA для аутентифікації. Ця аутентифікація здійснюється аутентифікаційні пакетами. Кожні logon-процес повинен зареєструвати себе в LSA при завантаженні системи, в той же момент він вибирає найбільш надійний аутентифікаційні пакет.

API, який повинен бути представлений в аутентифікаційних пакетах і API, доступний logon-процесу задокументовані в файлі LSAAUTH.HLP з Windows NT DDK.

WinLogon і MsV1_0

Стандартний logon-процес для інтерактивних входів в систему Windows NT називется Winlogon (WINLOGON.EXE). Він перехоплює спроби входу в систему з клавіатури.

При завантаженні WinLogon реєструє себе в LSA як logon-процесу, викликаючи функцію LsaRegisterLogonProcess. Таким чином він отримує хендл logon-процесу LSA і встановлює LPC з’єднання з портом LSA аутентифікації (\ LsaAuthenticationPort), який буде використаний для обміну інформацією в разі входу в систему, виходу з неї та проведення операцій над паролем.

Потім він отримує ідентифікатор для стандартного аутентифікаційні пакета, MSV1_0 (MSV1_0.DLL), викликавши LsaLookupAuthenticationPackage. Це той самий пакет, за допомогою якого проводитиметься автентифікація сертифіката користувача.

Какждого раз, коли WinLogon намагається забезпечити вхід користувача в систему, він викликає LsaLogonUser, вказуючи власний хендл logon-процесу LSA, ідентифікатор пакету Msv1_0 та ім’я користувача з паролем у виклику.

Процес завершується в LSAApLogonUserEx (функція знаходиться в MSV1_0.DLL), де ім’я користувача та пароль проходять аутентифікацію за допомогою віддаленої або локальної бази даних SAM, і де, якщо аутентифікація успішно пройдена, створюється сесія входу в систему шляхом виклику LsaCreateLogonSession і присвоєння їй LogonID (LUID), який генерується пакетом.

Після цього MSV1_0 додає додаткові сертифікати до сесії, за допомогою виклику LsaAddCredential. Такий сертифікат включає ім’я користувача, ім’я домену та контрольні суми LM / NT його / її пароля.

Ця інформація згодом використовується LAN-менеджером та іншими сервісами, коли користувач намагається отримати доступ до віддалених вузлів, і саме цю інформацію ми повинні змінити, щоб використовувати викрадене ім’я користувача та контрольні суми в атаці.

MSV1_0 отримує з бази даних SAM також SID користувача акаунтів і групи, до яких той належить, і передає цю інформацію процесу LSA-сервера, який, в свою чергу, отримує список привілеїв, відповідний екаунт і групам, і викликає NT Executive щоб створити Access Token (ідентифікує користувача і його права). Останній передається додатком WinLogon, яке запускає оболонку, як правило, EXPLORER.EXE.

Access Token зв’язується зі своєю LSA-сесією входу в систему за допомогою ідентифікатора AuthenticationID, який являє собою не що інше як LogonID, згенерована аутентифікаційні пакетом.

Зміна сертифіката MSV1_0

Обраний підхід до внесення змін в ці сертифікати грунтується на вивченні недокументованих структур, який процес сервера LSA використовує для зберігання сесій входу в систему та відповідних їм сертифікатів. Знаючи це ми можемо зайнятися безпосереднім зміною в області пам’яті сертифіката поточного користувача і підмінити їх на належні тому користувачеві, яким ми хочемо “стати”.

Не варто забувати, що багато чого в даному випадку грунтується на інтуїції і деякі висновки можуть бути неточними.

Процес LSA-сервера зберігає сесії в єдиному списку. Існує глобальна структура, в якій він зберігає покажчик на цей список і кількість створених сесій входу в систему (“стовідсоткового” методу знаходження це структури немає, вона знаходиться десь в LSASERV.DLL, бібліотеці, використовуваної LSA, де знаходяться функції і структури сесій входу в систему).

<br /> struct LsaLogonSessionArray { / / Покажчик на список<br /> uint32_t pLogonSessionsList; / / Кількість сесій входу<br /> uint32_t logonSessionsCount;<br /> };<br /> pLogonSessionsList &#8211; покажчик на простий список сесій входу в систему. Формат елемента списку такий:<br /> struct LsaLogonSession { / / Покажчик на наступну сесію<br /> uint32_t pNextLogonSession;<br /> // LogonId (LUID)<br /> uint32_t logonIDLow;<br /> uint32_t logonIDHigh; / / Покажчик на ім&#8217;я користувача в Unicode<br /> uint32_t pUNICODE_USERNAME; / / Покажчик на ім&#8217;я користувача в Unicode<br /> uint32_t pUNICODE_DOMAINNAME; / / Невідомий елемент. Схоже, покажчик на / / Іншу структуру, де серед іншого / / Знаходиться RID користувача<br /> uint32_t unkown1; / / Мабуть кількість посилань на logon-сесію<br /> uint32_t referenceCount; / / Покажчик на масив сертифікатів<br /> uint32_t pLsaCredentialsArray; };<br /> pLsaCredentialsArray вказує на іншу структуру під назвою LsaCredentialsArray. Якщо pLsaCredentials == 0 означає сесія входу в / / Систему не має ніяких пов&#8217;язаних з нею / / Сертифікатів.<br /> struct LsaCredentialsArray { / / Невідомо<br /> uint32_t unknown1; / / Невідомо<br /> uint32_t unknown2; / / Покажчик на сертифікат<br /> uint32_t pLsaCredentials[]; }; В ході даного дослідження не розглядалися сесії з більш ніж одним набором сертифіката, однак, є підстави вважати це масивом.<br /> pLsaCredentials зрештою приводить нас до сертифікату, створеному аутентифікаційні пакетом<br /> / / Сертифікат<br /> struct LsaCredentials { / / Невідомо<br /> uint32_t unknown1; / / Значення головного ключа в сертифікаті<br /> STRING PrimaryKey; / / Сертифікат<br /> STRING Credentials; }; Використовується STRING наступного формату:<br /> struct STRING {<br /> USHORT Length;<br /> USHORT MaximumLength;<br /> PCHAR Buffer; };<br />

Кожному сертифікату повинно бути присвоєно значення в PrimaryKey, рядку, яку згодом аутентифікаційні пакет може використовувати, щоб посилатися на цей сертифікат при виклику LsaGetCredentials. MSV1_0 як значення PrimaryKey використовує “Primary”.

Сертифікат не обов’язково представляє із себе рядок символів. У разі MSV1_0 Credentials.Buffer вказує на структуру типу:

<br /> struct MsvCredentials {<br /> UNICODE_STRING UNICODE_DOMAIN;<br /> UNICODE_STRING UNICODE_USERNAME;<br /> uint8_t NTHash[16];<br /> uint8_t LMHash[16];<br /> UCHAR domainname[UNICODE_DOMAIN.Length];<br /> UCHAR username[UNICODE_USERNAME.Length]; };<br />

Такі дані, які використовує LAN Manager і інші служби, які вдаються до допомоги аутентифікаційні пакета MSV1_0 для доступу до віддалених вузлів. Змінивши їх, можна проводити SMB / CIFS / MS RPC атаки за допомогою вкрадених з Windows NT Workstation / Server імені користувача / контрольної суми з пароля.

UNICODE_DOMAIN і UNICODE_USERNAME не звичайні рядки в Unicode, елемент Buffer не прямий покажчик на Unicode-рядок, а зсув від початку структури MsvCredentials. MSV1_0 надходить коли викликає LsaAddCredentials так, щоб зробити ці дані незалежними від адресного простору процесу.

Крім цього варто відзначити, що в Розділі 4.2 MSV1_0 (Credentials Formats) файлу LSAAUTH.HLP сказано, що сертифікати, що зберігаються MSV1_0 не містять імені домена, хоча насправді це не так.

Враховуючи все вищесказане, послідовність дій для зміни сертифіката входу в систему наступна.

Отримати Access Token AuthenticationId поточного користувача. Це легко можна зробити за допомогою WIN32 API:

/ / Отримуємо Access Token поточного порцесса<br /> OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &#038;hToken); / / Отримуємо статистичну інформацію<br /> GetTokenInformation( hToken, TokenStatistics, &#038;tokenstats,<br /> sizeof(tokenstats), &#038;len) / / Елемент AuthenticationId повернутої / / Структури типу TOKEN_STATISTICS / / Містить ідентифікатор входу в систему / / Logon ID відповідний даному Token.<br /> logonID = tokenstats.AuthenticationId;<br />

Це найменш глибокий спосіб зміни сертифіката і дозволить вам тільки змінити контрольні суми LM і NT користувача. Чому? Тому що вони мають фіксовану довжину (16 байт кожна) і досить просто записати поверх них нові. Проте ім’я користувача та домену – рядки в Unicode, які змінюють довжину і ви повинні заново виділяти пам’ять під новий блок сертифіката, щоб замінити їх більш довгими. (Наприклад, якщо ім’я користувача – “MyUser” і ви хочете замінити його на “MyAnotherUser”, вам знадобиться більший буфер для нової Unicode-рядка).

В даному випадку це може бути вирішено шляхом чергового введення dLL в адресний простір LSASS.EXE і викликами LsaDelCredential і LsaAddCredential як вчинив би MSV1_0, щоб замінити цілком сертифікат на новий з іншими Ім’ям користувача та паролем.

Висновок. Зміна сертифікатів входу в систему дозволяє атакуючому використовувати Windows NT атаки за допомогою вкрадених імен користувача / контрольних сум. Воно дозволяє віддалене управління атакується сервером, яке раніше було б неможливим без самих паролів. Воно не є новою діркою в безпеці само по собі, але, безсумнівно, розширює можливості зломщика.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*