Магия SSPI. Достаем учетные данные Windows, не трогая LSASS

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

  • Реквизиты, контекст и блобы
  • Известные атаки
  • Внутренний монолог
  • Выводы

Windows поз­воля­ет раз­работ­чикам соз­давать шиф­рован­ные каналы свя­зи, под­писывать сооб­щения меж­ду кли­ентом и служ­бой, аутен­тифици­ровать кли­ента на служ­бе. Зло­упот­ребляя эти­ми воз­можнос­тями, мы можем извле­кать учет­ные дан­ные поль­зовате­ля без вза­имо­дей­ствия с LSASS. В этой статье я про­демонс­три­рую, как это работа­ет.

Security Support Provider Interface (SSPI) — это механизм, пре­дос­тавля­ющий огромный набор фун­кций для раз­работ­чиков. Сре­ди его пре­иму­ществ:

  • не­зави­симость от тран­спор­та (дан­ные переда­вать мож­но любым обра­зом);
  • об­щий для всех SSP интерфейс;
  • аутен­тифика­ция (в том чис­ле с заимс­тво­вани­ем прав);
  • кон­фиден­циаль­ность сооб­щений (шиф­рование);
  • сох­ранность сооб­щений (циф­ровая под­пись).

SSP, если ты не читал мою прош­лую статью, — это набор DLL-фай­лов, который поз­воля­ет исполь­зовать про­токо­лы безопас­ности (NTLMSSP, Kerberos и иные) в кли­ент‑сер­верных про­цес­сах. Если силь­но обоб­щить, то SSPI — это API для вызова заг­ружен­ных в сис­тему SSP.

 

Реквизиты, контекст и блобы

SSPI соз­дает так называ­емые security blobs. По‑рус­ски — «эле­мен­ты безопас­ности» или «ком­понен­ты безопас­ности», но офи­циаль­ного перево­да мне не попада­лось, так что оста­новим­ся на «бло­бах». Эти­ми самыми бло­бами кли­ент и сер­вер обме­нива­ются по удоб­ному для них про­токо­лу.

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

Пу­тем обме­на бло­бами выс­тра­ивает­ся кон­текст. Кон­текст — спе­циаль­ный объ­ект, который хра­нит­ся и на кли­енте, и на сер­вере. Кон­текст — резуль­тат успешной аутен­тифика­ции кли­ента на сер­вере и в некото­рых слу­чаях — сер­вера на кли­енте. С помощью выс­тро­енно­го кон­тек­ста мож­но исполь­зовать весь потен­циал SSPI. Нап­ример, мож­но пос­тро­ить кон­текст, получить хендл, а затем шиф­ровать переда­ваемые меж­ду кли­ентом и сер­вером сооб­щения. При­чем сер­вер смо­жет рас­шифро­вать сооб­щения, так как у него есть кон­текст, сге­нери­рован­ный вмес­те с кли­ентом, на котором дан­ные шиф­руют­ся.

Итак, для пос­тро­ения кон­тек­ста исполь­зуют­ся спе­циаль­ные фун­кции AcceptSecurityContext() и InitializeSecurityContext(). Кон­текст выс­тра­ивает­ся не сра­зу. Если тре­бует­ся еще пару раз обме­нять­ся бло­бами с сер­вером или кли­ентом, то воз­вра­щает­ся ошиб­ка SEC_I_CONTINUE_NEEDED.

Ду­маю, зву­чит страш­но. Давай визу­али­зиру­ем. Пос­тро­ение кон­тек­ста на сто­роне кли­ента выг­лядит сле­дующим обра­зом.

SSPI на кли­енте

Кли­ент сна­чала получа­ет хендл на свои рек­визиты с помощью фун­кции AcquireCredentialsHandle(), затем начина­ет выс­тра­ивать кон­текст, исполь­зуя бло­бы. Как толь­ко фун­кция InitializeSecurityContext() перес­тала воз­вра­щать SEC_I_CONTINUE_NEEDED, мож­но счи­тать, что кон­текст выс­тро­ен, и поль­зовать­ся все­ми фун­кци­ями SSPI.

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

Ответить

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