Локальная картошка. Исследуем уязвимость в локальной аутентификации Windows

Содержание статьи

  • NTLM-аутентификация
  • Локальная аутентификация NTLM
  • Как работает LocalPotato
  • StorSvc и DLL hijacking
  • Компиляция эксплоита
  • Эксплуатация
  • Вывод

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

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

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

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

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

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

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

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

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

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

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

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

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

     

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

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

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

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

    StorSvc и DLL hijacking

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

    Источник: xakep.ru

    Ответить

    Ваш адрес email не будет опубликован. Обязательные поля помечены *