В этой статье речь пой­дет об уяз­вимос­ти, поз­воля­ющей выпол­нить локаль­ное повыше­ние при­виле­гий (LPE) в опе­раци­онных сис­темах семей­ства Windows. Баг нап­рямую свя­зан с NTLM-аутен­тифика­цией, поэто­му сна­чала погово­рим о том, как она устро­ена, а потом перей­дем непос­редс­твен­но к раз­бору CVE-2023-21746.
 

NTLM-аутентификация

Пред­положим, поль­зователь хочет получить дос­туп к фай­ловому ресур­су на дру­гом компь­юте­ре или сер­вере. Аутен­тифика­ция выпол­няет­ся в четыре эта­па:

  1. Поль­зователь отправ­ляет сер­веру зап­рос с име­нем учет­ной записи.
  2. В ответ сер­вер отправ­ляет ему слу­чай­ное чис­ло, называ­емое challenge.
  3. Поль­зователь шиф­рует это чис­ло сво­им NT-хешем и отправ­ляет обратно.
  4. Сер­вер извле­кает из SAM (Security Account Manager — RPC-сер­вер Windows, опе­риру­ющий базой дан­ных учет­ных записей) хеш поль­зовате­ля и про­делы­вает те же самые дей­ствия, что и поль­зователь, срав­нивая получен­ные хеши. Если резуль­таты сов­пали, то аутен­тифика­ция счи­тает­ся успешной.
 

Локальная аутентификация NTLM

Рас­смот­рим локаль­ную аутен­тифика­цию NTLM, которая начина­ется с аутен­тифика­ции поль­зовате­ля на самой машине.

Эта аутен­тифика­ция выпол­няет­ся сле­дующим обра­зом:

  1. Поль­зователь вво­дит свои учет­ные дан­ные, логин и пароль, при вхо­де на машину.
  2. Вве­ден­ные дан­ные переда­ются под­систе­ме локаль­ной безопас­ности LSA, которая пре­обра­зует пароль в хеш.
  3. Да­лее LSA переда­ет имя поль­зовате­ля SAM, который извле­кает хеш ука­зан­ного поль­зовате­ля.
  4. LSA све­ряет хеши, и если они сов­пада­ют, то поль­зователь получа­ет дос­туп к машине.

Да­лее сра­баты­вает рас­смот­ренный выше механизм, осно­ван­ный на модели кли­ент — сер­вер.

Ло­каль­ная аутен­тифика­ция NTLM — это час­тный слу­чай, она при­меня­ется, ког­да кли­ент­ская и сер­верная час­ти работа­ют на одной машине.

Кли­ент получа­ет учет­ные дан­ные вошед­шего в сис­тему поль­зовате­ля и соз­дает зап­рос, содер­жащий имя рабочей стан­ции и домена кли­ента.

Со­обще­ние типа 1. Кли­ент посыла­ет это сооб­щение для начала соеди­нения. Оно исполь­зует­ся для сог­ласова­ния парамет­ров аутен­тифика­ции, как и рань­ше, но так­же содер­жит имя кли­ент­ской машины и ее домен. Сер­вер может про­верить имя и домен кли­ента, и, если они сов­пада­ют с его собс­твен­ными, начина­ется про­цесс локаль­ной аутен­тифика­ции.

Со­обще­ние типа 2. Сер­вер соз­дает кон­текст безопас­ности, вызывая фун­кцию AcceptSecurityContext (NTLM), и в этом сооб­щении отправ­ляет кли­енту его иден­тифика­тор. Затем кли­ент может исполь­зовать иден­тифика­тор кон­тек­ста безопас­ности, что­бы свя­зать себя с соеди­нени­ем.

Со­обще­ние 3-го типа. Кли­ент получа­ет токен и переда­ет его в InitializeSecurityContext (NTLM). Если InitializeSecurityContext (NTLM) воз­вра­щает SEC_E_OK, то вза­имная аутен­тифика­ция завер­шена и мож­но начинать защищен­ный сеанс. Если же он воз­вра­щает код ошиб­ки, то перего­воры о вза­имной аутен­тифика­ции завер­шают­ся. В про­тив­ном слу­чае токен безопас­ности, воз­вра­щен­ный InitializeSecurityContext (NTLM), отправ­ляет­ся кли­енту и шаги 2 и 3 пов­торя­ются.

 

Как работает LocalPotato

LocalPotato исполь­зует недос­таток в механиз­ме локаль­ной аутен­тифика­ции NTLM. Экс­пло­ит обма­ныва­ет при­виле­гиро­ван­ный про­цесс и зас­тавля­ет аутен­тифици­ровать сеанс, запущен­ный хакером. В резуль­тате ата­кующий получа­ет соеди­нение, пре­дос­тавля­ющее ему дос­туп к любым ресур­сам с при­виле­гиями обма­нуто­го про­цес­са.

«Кар­тошка» работа­ет сле­дующим обра­зом:

  1. Ха­кер запус­кает при­виле­гиро­ван­ный про­цесс для под­клю­чения к под­кон­троль­ному ему сер­веру. В прин­ципе, это работа­ет ана­логич­но пре­дыду­щим Potato, ког­да неп­ривиле­гиро­ван­ный поль­зователь зас­тавлял ОС соз­давать соеди­нения, исполь­зующие пра­ва SYSTEM.
  2. Сер­вер на машине соз­даст кон­текст безопас­ности А для при­виле­гиро­ван­ного соеди­нения, но не будет отправ­лять его сра­зу. Хакер запус­тит свой кли­ент, что­бы он одновре­мен­но с локаль­ным ини­цииро­вал соеди­нение с сер­вером. Легитим­ный кли­ент отправ­ляет сооб­щение, что­бы ини­цииро­вать соеди­нение, а сер­вер в ответ пош­лет сооб­щение с иден­тифика­тором нового кон­тек­ста безопас­ности Б.
  3. Зло­умыш­ленник так­же запус­кает свой сер­вер и меня­ет иден­тифика­торы кон­тек­стов обо­их соеди­нений таким обра­зом, что­бы при­виле­гиро­ван­ный про­цесс получил кон­текст соеди­нения с сер­вером зло­умыш­ленни­ка, а не со сво­им собс­твен­ным. В резуль­тате хакер смо­жет получить дос­туп к любому сетево­му ресур­су с при­виле­гиями SYSTEM.
 

StorSvc и DLL hijacking

До сих пор мы исполь­зовали LocalPotato для записи любых фай­лов на целевую машину. Что­бы получить при­виле­гиро­ван­ную обо­лоч­ку, нам нуж­но выяс­нить, как исполь­зовать про­изволь­ную запись для выпол­нения коман­ды.

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

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


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

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

    Подписаться

  • Подписаться
    Уведомить о
    1 Комментарий
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии