LockedShields 2o25

w tym roku po raz kolejny stanęliśmy na podium LockedShields, organizowanego przez CCDCOE. POL-FRA drużyna stanęła na wysokości zadania, minimalnie ustępując drużynie z Niemiec.

to ważne wydarzenie dla mnie co roku – zupełnie inne spojrzenie na bezpieczeństwo i pracę w stanie wysokiego stresu. przez 3 dni miałem dostarczane jedzenie na biurko, a wypad na siku raportowany resztom osób, bo przez 2 min nie jestem w stanie wspierać reszty teamu. świetny trening, który przypomina mi, jak bardzo różni się dzień powszedni od sytuacji kryzysowej. trzeba wykrzesać z siebie więcej, pracować inaczej, a 'książkowe zasady’, które stosuje się na co dzień do zabezpieczania systemów nagle stają się farsą i trzeba rzeczy adresować zupełnie inaczej.

pomimo wysokiej lokaty ten rok wyjątkowo oberwaliśmy [jako team AD] – szacun dla Red Teamu, tym razem nas wyprzedzili. ale to dobrze – chodzi o to, żeby się rozwijać, nie spocząć na laurach i co rok odtwarzać te same procedury. co z takich ćwiczeń się wynosi to tzw 'drill’:

  • praca w nietypowych warunkach wymagająca podejmowania natychmiastowych decyzji
  • hierarchia i wykonywanie rozkazów – wbrew pozorom, bardzo trudne dla cywilnych IT. mamy swoją dumę, wielu z nas w wojsku nie było i przyzwyczajeni do brylowania w środowiskach, w których pracujemy, wcale nie jest łatwo utrzymać hierarchię, słuchać rozkazów. starcie charakterów, umiejętność 'zamknięcia się’ i po prostu zrobienia czegoś, nawet jak się z tym nie zgadzamy czy przekazane jest zbyt dosadnie… komunikacja i zarządzanie kryzysowe 'w praktyce’ to co innego niż narysowanie drzewka na papierze.
  • przestrzeganie procedur ale i umiejętność improwizacji, kiedy zawodzą

do tego oczywiście duża dawka wiedzy od reszty zespołów, co też ma swoje znaczenie, jednak IMHO 'drill’ w takich sytuacjach jest najcenniejszym doświadczeniem.

wiele food for though na przyszły rok po otrzymaniu wyników – mam szczerą nadzieję, iż będę miał zaszczyt i okazję poprawić ochronę naszej części środowiska i udowodnić, że się rozwijamy – technicznie i i w zakresie zarządzania kryzysowego.

dziękuję gorąco całemu zespołowi LS25 i wielkie kudos dla organizatorów, bo impreza jest na na prawdę wysokim poziomie!

PS. dla wszystkich, którzy chcieliby wesprzeć kraj jako cywile – Dowództwo Komponentu Wojsk Obrony Cyberprzestrzeni uruchomiło program CyberLEGION.

eN.

Authentication Methods – wymuszenie telefonu dla ról uprzywilejowanych (MSP)

Authentication Methods pozwalają w granularny sposób skonfigurować, które metody uwierzytelnienia działają, a które nie. Dobrze jest, zgodnie z zaleceniami, wyłączyć uwierzytelnienie przez telefon – zarówno połączenie głosowe jak SMS, ponieważ te metody są stosunkowo łatwe do złamania

Najlepiej więc te metody wyłączyć. Przy okazji przypomnę, że warto zmigrować do nowego modelu MFA, z procesu którego pochodzi poniższy obrazek:

Tutaj pojawia się ciekawostka, której nie znalazłem w żadnym artykule:

  • Konta należące do rol uprzywilejowanych mają te metody włączone bez względu na ustawienia

Czyli nawet jeśli wykona się wszystkie kroki – pełną migracją do nowego modelu, wyłączy SMS i voice, konto należące np. do roli Global Administrator czy choćby User Administrator, nadal będą mieli ekrany zmuszające do ustawienia telefonu… jest opcja 'choose another method’ – i tutaj też lekkie zaskoczenie – dostępny jest hardware token, phone oraz email.

A więc te najważniejsze konta mają zakodowane najmniej bezpieczne metody. Oczywiście – jeśli jest to konto:

  • dla konkretnego administratora, w konkretnej firmie
  • break glass account

fizyczny klucz FIDO2 rozwiązuje temat. powinien wręcz być podstawową sugestią wizarda konfiguracji konta.

problem pojawia się w środowisku gdzie pojedyncze konto używane jest przez wielu operatorów – myślę głównie o środowiskach MSP… „HEREZJA!” chciałoby się krzyknąć. sytuacja niedopuszczalna – żeby jedno konto było współdzielone przez kilku użytkowników. zasadniczo tak właśnie jest – nie powinno się współdzielić kont, ponieważ łamie to podstawowe zasady bezpieczeństwa, choćby 'Accounting’ z AAA principle, nie pozwalając na jednoznaczną identyfikację 'kto wykonał operację’. są inne, prawidłowe metody zarządzania:

  • indywidualne konta i PIM. perfekcyjne dla dużych firm ale dla małych koszty EID P2 są duże, a w przypadku MSP posiadanie wielu kont dla całej obsługi, w każdym zarządzanym tenancie jest nierealne
  • GDAP dla MSP. świetna idea, ale niestety Microsoft nigdy nie potrafił wdrożyć jest dobrze. portal partnerski był kupą i nią pozostał nawet po pełnym liftingu. jak ktoś raz na miesiąc potrzebuje coś sprawdzić to pewnie zbierze się na cierpliwość żeby skorzystać z tego narzędzia, ale do codziennej administracji potrzeba byłoby zatrudniać mistrzów ZEN. poza prędkością działania, to się po prostu sypie i nie wszystkie operacje są obsługiwane, część po prostu wymaga bezpośrednio zalogowania się jako GA.
  • różne aplikacje firm 3-cich, które mają pełny dostęp i własny model bezpieczeństwa. wprowadzają dodatkową warstwę abstrakcji, dając możliwość uwierzytelnienia z centralnego, zintegrowanego tenanta MSP czyli zapewniają audyt zmian, pod spodem działając przez GraphAPI. brzmi nieźle – i to kolejne fajne rozwiązanie dla większych, ale ze względu na koszty (głównie związane z utrzymaniem i wprowadzaniem dodatkowej złożoności) – znów sprawia problemy mniejszym firmom.
  • można też oczywiście przygotować wiele kluczy FIDO2 tak, żeby każdy miał swój. to chyba w miarę najprostsza metoda. choć niezbyt tania, to jest to jednorazowy koszt w przeciwieństwie do comiesięcznych subskrypcji i utrzymania…

Microsoft zawsze przede wszystkim patrzył na Enterprise, pozostawiając mniejszych trochę na pastwę nieprawidłowych praktyk. to w sumie niuans, ale w czasach, w których codziennie padają kolejne firmy i co chwilę pada kolejny rekord w kwestii tego ile danych udało się wydobyć czy co złamać, takie niuanse nie pozostają bez znaczenia.

eN.

Locked Shield 2o24

Po raz trzeci miałem zaszczyt uczestniczyć w największych ćwiczeniach (zawodach?) niebezpieczeństwa, organizowanych przez CCDCOE (NATO Cooperative Cyber Defence Centre of Excellence) i po raz kolejny skończyliśmy na podium. przez zamieszanie z punktami ciężko powiedzieć czy na 1 czy na 2 miejscu ale jedno jest pewne – co roku Polska drużyna jest wśród najlepszych!

od zeszłego roku dodatkowym celem ćwiczenia jest wymiana wiedzy i nauka koordynacji zadań między krajami, występuje się w parach – w tym roku walczyliśmy ramię-w-ramię z Finami.

i choć ćwiczenia odbywały się w strefie czasowej CET, co oznaczało dla mnie przestawienie dnia i olbrzymi wysiłek – nie żałuję. to świetne doświadczenie i jestem dumny z naszego wyniku. „dywizja AD” (; trzymała się świetnie przez cały czas pozostając all-green w zasadzie od początku do końca. trochę nas postraszyli w ostatniej fazie, ale daliśmy radę i to rozwiązać szybko i sprawnie.

szczególne podziękowania dla naszego leadera – Grześka i pozostałych członków teamu AD – Roberta, Tomka i Marka.

eN.

LockedShields 2o23

LockedShields 2o23

jako fan społeczności i pracy organicznej, cieszą mnie inicjatywy, w których duże organizacje – rządowe, czy militarne – starają się budować i wspierać społeczności, rozumiejąc jak ważną rolę pełnią. zwłaszcza w czasach niepokoju, a takie teraz mamy, super-istotne jest, żeby ludzie umieli się organizować w warunkach rozproszenia, pod silną presją, bez centralnego dowodzenia, samodzielnie decydując i działając. żeby umieli się wspierać i podejmować akcje.

tym właśnie jest ćwiczenie LockedShields, organizowane przez CCDCOE a w Polsce przez Wojska Obrony Cyberprzestrzeni. po raz drugi miałem zaszczyt wziąć udział w tym wydarzeniu, jako członek Blue Team i wspólnie wywalczyliśmy 3cie miejsce. biorąc pod uwagę, iż udział bierze 38 krajów z krajów NATO, konqrencja jest na prawdę zaciekła i decydują szczegóły – więc choć chciałoby się więcej, trzecie miejsce jest świetnym wynikiem i jestem szczerze dumny, że mogłem się do niego przyczynić.

dużo nauki, świetna ekipa, niesamowici specjaliści i atmosfera współpracy – wszystko to, co powoduje, że chce się być częścią tej społeczności (: nie sposób podziękować całemu zespołowi, ale szczególne kudosy dla pozostałych obrońców Active Directory w tym roq: Robert PrzybylskiTomasz Rupiewicz i Marek Żach. chociaż daliśmy radę chronić usługę świetnie, i zajęliśmy #1 [jako cały Blue Team] w dostępności usług, jak zwykle dużo do analizy po ćwiczeniu, tzw. lesson-learned.

oficjalnie od Wojska Polskiego.

samotny wilk, eN.

 

Passwordless dla Microsoft Account

niedawno Microsoft ogłosił funkcję 'passwordless’ dla kont 'Microsoft Account’ – czyli tych nie-firmowych/nie-szkolnych. wszystkie arty dot. braq haseł rozpływają się w zaletach tego rozwiązania i ah, oh [fapfap] … więc daruję sobie powtarzanie zalet braq hasła. funkcję włączyłem i … obniżyłem sobie bezpieczeństwo dostępu.

trzeba jasno odgrodzić passwordless dla firm i funkcje Windows Hello for Business, który zakłada MultiFactor Auth – z naciskiem na ’Mutli’, od passwordless dla kont MS. zastanawiałem się jak to będzie praktycznie zrealizowane, włączyłem –  i osobiście mnie to trochę przeraża – ponieważ z MFA wracamy do Single Factor Auth, którym jest nasz smartfon. nie spodziewam się, aby wiele osób miało na kontach dane warte ucięcia komuś kciuka [i przechowywania w odpowiednich warunkach], ale mimo wszystko logowanie, w którym JEDYNYM czynnikiem jest kliknięcie na ekranie telefonu, budzi u mnie alarm. jakiś czas temu, o ile pamiętam, była opcja dodatkowego zabezpieczenia apki Microsoft Authenticator PINem. dziś znajduję w opcjach jedynie 'require biometric or PIN’ ale bez możliwości wyboru – wygląda na to, że ustawienie pobierane jest z systemu (sprawdzałem na Android) – a więc czy będzie to odcisk, czy PIN – będzie to TEN SAM odcisk/PIN, co do reszty. ciekawy jestem czy ta formuła faktycznie zadziała – dowodem będzie, że przez najbliższe kilka lat będzie funkcjonować w tej postaci, będzie używana, a w prasie nie zaczną się pojawiać arty o tym jak to wypłynęła porcja danych/zdjęć/doqmentów bo ktoś zgubił smartfona. imho bardzo szybko pojawi się nowa wersja apki lub ustawienie, które doda jakiś drugi czynnik – może PIN, może kod SMS, czy choćby wybór obrazka. co ciekawe w ustawieniach konta nadal widzę 'Two-step auth ON’ – pomimo, że loguję się teraz tylko przykładając palec do ekranu.

niezależnie od mojej subiektywnej opinii, każdy powinien zrewidować swoje ustawienia haseł i upewnić się:

  • czy na pewno mamy skonfigurowane dodatkowe metody uwierzytelnienia?
  • czy je pamiętamy? [np. czy znamy odpowiedzi do pytań weryfikacyjnych]
  • czy ustawienia tych metod nie zapętlają się?

jeśli naszą drugą metodą jest adres email, który ma włączone MFA oparte o tą samą apkę – to tracąc telefon nie zalogujemy się nigdzie. powinniśmy mieć realną alternatywę inaczej czeka nas długie przebijanie się przez support. jeśli coś takiego wydarzy się gdy nie mamy czasu, będziemy w kropce. każdy powinien poświęcić czas chociaż raz, i 'na niby’ zgubić telefon. wyłączyć go i sprawdzić gdzie jest w stanie się zalogować, czego braqje, ile to trwa czasu. w firmach na podobne scenariusze powinny istnieć procedury, ale sprawę ułatwia, że zazwyczaj jest kilq administratorów, więc w większości scenariuszy są sobie w stanie pomóc na wzajem. prywatnie, nas czeka przebijanie się przez linie wsparcia – warto przynajmniej spróbować, żeby oszacować ile to może trwać czasu i jak w ogóle taka procedura wygląda.

z jednej strony firmy dwoją się i troją, żeby było bezpieczniej a zarazem łatwiej… wygoda na pewno się zwiększa – ale w momencie kiedy coś się sypnie, zaczynają się schody. i wcale nie jest łatwo wymyśleć i skonfigurować swoje konta tak, aby faktycznie odzyskać awaryjnie dostęp szybko i bezpiecznie.

ciekaw jestem opinii – bo na razie nie trafiłem na te negatywne czy krytyczne. moja jest dość mieszana – niby wygodnie, ale [w przypadku kont prywatnych] na pewno nie bezpieczniej!

eN.

 

bezpieczne hardcodowanie hasła w skrypcie

bezpieczne hardocodowanie hasła?

uruchamiając skrypt, najbezpieczniej jest NIE hardcodować hasła. jeśli coś jest w skrypcie, to znaczy, że może być wykorzystane w nieautoryzowany sposób. jednak przykłady z życia pokazują, że czasem taka jest konieczność .. czy po prostu zlecenie (; przykład – obsługa wsparcia, która ma korzystać ze skryptu, który gdzieś tam sobie sięga. to 'gdzieś tam’ to środowisko, w którym nawet owa obsługa nie ma konta.

podstawowe zasady bezpieczeństwa to 3xA (AAA) – Authentication, Authorization & Accounting. jeśli utworzymy konto serwisowe, które ma coś wykonywać w imieniu uruchamiającego, to aby nie złamać zasady AAA i być w stanie stwierdzić kto wykonał daną akcję, trzeba to przesunąć do miejsca, gdzie uruchamia się skrypt/aplikację i umieć to powiązać… dalej mogłoby być o SIEM i tak dalej… ale nie o tym tutaj. ogólnie najważniejsze – wykorzystanie konta serwisowego (w środowisq legacy-domain), czy aplikacji proxy (tak jak działa to w Azure) nie musi koniecznie być złem, ale pozostaje pytanie… *jak zamieścić hasło skrypcie tak, aby nie wyciekło wraz ze skryptem?*

najbezpieczniej byłoby wykorzystać certyfikat… tak to można zrobić np. dla aplikacji Azure. niestety w środowisq klasycznym, gdzie mamy np. wykonać akcję w domenie, nie jest to łatwe. najbezpieczniej byłoby umieszczenie serwisu aka proxy, który działa sobie na serwerze w owej domenie i do tegoż serwisu uwierzytelniać się certyfikatem. spoko ale to developerka i do 'małych projekcików’ czy 'drobnych narzędzi’ – po prostu jest za duża czasochłonność (czyt. koszt), nie wspominając o tym że napisanie własnego serwisu (np. wystawiającego REST API) to nie jest już skryptowanie. to developerka.

no więc zróbmy to, co da się zrobić tak, aby było szybko i *możliwie* bezpiecznie.

…na ile się da

skoro nie jesteśmy w stanie uwierzytelnić się certyfikatem, to przynajmniej zaszyfrujmy hasło certyfikatem. co nam to da:

  • dany skrypt będzie działał wyłącznie na tej maszynie gdzie jest certyfikat i dla tych osób, którym na to pozwolimy.

żeby była jasność – jeśli ktoś, kto ma złe intencje będzie tego skryptu używał, to sobie hasło odkoduje. ale po pierwsze – 'pierwszy lepszy’ tego nie zrobi, po drugie – jeśli założylibyśmy takiej osobie konto, to i tak wykorzysta je do niecnych celów. trzeba wiedzieć że to może być rozwiązanie *good enough* i tylko w tym kontekście można nazwać je 'bezpiecznym’. spory disclaimer ale nie chcę przypadkowych czytelników wprowadzić w błąd.

jak już wyjaśniłem co rozumiem przez 'bezpieczne’, recepta:

  1. załóż konto w domenie, bez żadnych dodatkowych uprawnień
  2. dobrze byłoby poustawiać 'deny’ dla takiego konta, przykrajając odpowiednio uprawnienia – wedle potrzeby, uznania i paranoia-level
  3. nadać uprawnienia do tego, do czego będzie wykorzystywane
  4. wygenerować odpowiedni certyfikat, zainstalować go i odpowiednio nadać uprawnienia
  5. zaszyfrować hasło certyfikatem
  6. i voila.. można go wykorzystać w skrypcie

punkty 1-3 pominę, natomiast 4-6 zaraz opiszę.

dzięki takiej konfiguracji – skrypt, nawet skopiowany czy przypadkowo udostępniony, na niewiele się zda. aby wydobyć hasło – trzeba mieć dostęp do klucza prywatnego certyfikatu.

generowanie certyfikatu

super proste, przy czym do tego celu cert musi spełniać odpowiednie funkcje, czyli (nomen-omen) kluczem jest dobry key-usage i document type:

$cert=New-SelfSignedCertificate -DnsName "script automation" -CertStoreLocation "Cert:\CurrentUser\My" -KeyUsage KeyEncipherment,DataEncipherment,KeyAgreement -Type DocumentEncryptionCert

$cert|Export-PfxCertificate -FilePath C:\temp\scriptautomation.pfx -Password (ConvertTo-SecureString -String "secret-string" -Force -AsPlainText)

dodatkowo można certyfikat usunąć z własnego komputera tak, aby jedna kopia była w pliq:

$cert|remove-Item

…albo zachować go jako backup a usunąć potem plik. up2u.

instalacja w środowisq docelowym

najłatwiej oczywiście kliknąć sobie na pliq pfx i wybrać opcję 'local machine’. jeśli umieścimy w 'current user’ to będzie dostępny tylko dla nas.

kolejną hiper-istotną kwestią jest *NIE włączanie* możliwości exportu klucza.

jeśli ktoś woli z PowerShell – należy użyć ’import-pfxCertificate*bez* parametru -exportable.

Import-PfxCertificate -FilePath C:\temp\scriptautomation.pfx -Password (ConvertTo-SecureString -string "secret-string" -force -AsPlainText) -CertStoreLocation Cert:\LocalMachine\My\

ciekawostka: w PS 5.1 ten commandlet ma dodatkowy parametr, nieopisany w doc, protectPrivateKey, który pozwala wykorzystać Virtual Secure Mode.

to połowa sukcesu – bo do tak zaimportowanego certyfikatu, nikt bez uprawnień administratora nie będzie mógł skorzystać. należy nadać uprawnienia do klucza prywatnego:

  1. odpal 'certlm.msc’ (zarządzanie certyfikatami komputera)
  2. wybierz certyfikat i kliknij PGM
  3. jest tam opcja 'manage private keys…’

4. nadaj uprawnienie READ (nie FC!) dla wybranych osób

kodowanie i odkodowanie hasła

teraz już z górki. przygotowanie środowiska to bardziej wymagający element, ponieważ hasło można zaszyfrować za pomocą polecenia ’protect-cmsMessage’:

C:\_scriptz :))o- Protect-CmsMessage -To 'cn=script automation' -Content 'moje tajne hasło'
-----BEGIN CMS-----
MIIBtAYJKoZIhvcNAQcDoIIBpTCCAaECAQAxggFMMIIBSAIBADAwMBwxGjAYBgNVBAMMEXNjcmlw
dCBhdXRvbWF0aW9uAhB2BdZafxn2nkcWjQNvBi+pMA0GCSqGSIb3DQEBBzAABIIBAFY0TU8LAPl4
4IAWp9tGDOZK/bAEwQpZPix5dz8AoOpaDckpZ8dqatggEKq7vo4VX6wL4sBkImQoZrCZjkT7oCSi
N1YFDOIghjD7e2mIvEl/Gq2bReUbsFQ0iw6Wg1K8zVLBzDQAIUHgJvaV2Ssf4nCJ8WfW5d9UzmBB
JpHAmy7cdofboQt6hRz0wafGNivD47z2xNSSVyhqHVUzBt6NWmAYouFMGYGsBZBuOHXnQJzh+saG
Q5VpWxZGRHzM3igl8IgYDF75R+b/FSfciPu5Se2eeD6xxHrPj9rfLm37KVIab/4+QA/lRFVt4cwA
ztjhh8puyPqYgKCE7t0Tp5VNQv4wTAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQjmYztOm64boC
6XqnH/9kMYAgYTQlOXeGex7qMH5S5gVRKy/JOhfIdqlabP9e/N/6iRk=
-----END CMS-----

ciekawostka: przy tym mechaniźmie szyfrowania (Cryptographic Message Syntax), uruchomienie tego polecenia, da za każdym razem inny wynik

jeśli ktoś nie pamięta nazwy certu, to można je szybko wylistować:

C:\_scriptz :))o- ls Cert:\LocalMachine\My\

PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My

Thumbprint Subject
---------- -------
B643393E34BDC10BE2266F307F63A712578416F1 CN=script automation

wkleić sobie ten ciąg do skryptu i kiedy potrzebne jest hasło, użyć unprotect-CMSMessage… np. tak:

[string]$encPass="-----BEGIN CMS----- 
MIIBtAYJKoZIhvcNAQcDoIIBpTCCAaECAQAxggFMMIIBSAIBADAwMBwxGjAYBgNVBAMMEXNjcmlw
dCBhdXRvbWF0aW9uAhB2BdZafxn2nkcWjQNvBi+pMA0GCSqGSIb3DQEBBzAABIIBAFY0TU8LAPl4
4IAWp9tGDOZK/bAEwQpZPix5dz8AoOpaDckpZ8dqatggEKq7vo4VX6wL4sBkImQoZrCZjkT7oCSi
N1YFDOIghjD7e2mIvEl/Gq2bReUbsFQ0iw6Wg1K8zVLBzDQAIUHgJvaV2Ssf4nCJ8WfW5d9UzmBB
JpHAmy7cdofboQt6hRz0wafGNivD47z2xNSSVyhqHVUzBt6NWmAYouFMGYGsBZBuOHXnQJzh+saG
Q5VpWxZGRHzM3igl8IgYDF75R+b/FSfciPu5Se2eeD6xxHrPj9rfLm37KVIab/4+QA/lRFVt4cwA
ztjhh8puyPqYgKCE7t0Tp5VNQv4wTAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQjmYztOm64boC
6XqnH/9kMYAgYTQlOXeGex7qMH5S5gVRKy/JOhfIdqlabP9e/N/6iRk=
-----END CMS-----"

try {
  $cert = Get-ChildItem Cert:\LocalMachine\My\B643393E34BDC10BE2266F307F63A712578416F1 -ErrorAction stop
} catch {
  write-log "missing authentication certificate. quitting" -type error
  retrun $null
}
  if(-not $cert.HasPrivateKey) {
  write-log "missing decription factor. quitting." -type error
  return $null
}
  $certCN = $cert.Subject
try {
  [securestring]$secStringPassword = ConvertTo-SecureString (Unprotect-CmsMessage -Content $encPass -To $certCN -ErrorAction stop) -AsPlainText -Force
} catch {
  write-log "error decrypting auth password $($_.exception)" -type error
  return $null
}
[pscredential]$creds = New-Object System.Management.Automation.PSCredential ('CORP\SVC-contactCreator', $secStringPassword)

inne scenariusze i metody

jakiś czas temu linkowałem dostęp do EXO certyfikatem. wygodne.

a podczas uruchamiania własnych skryptów, i tam gdzie wystarczą zwykłe credsy, nie chce mi się wpisywać hasła. zapisuję więc je sobie do pliq:

if(test-path $credsFile) {
    $myCreds = Import-CliXml -Path $credsFile
    write-log "used saved credentials in $credsFile" -type info
} else {
    $myCreds=Get-Credential
    if($NULL -eq $myCreds) {
        write-log 'Cancelled.' -type error
        exit -3
    }
    if($saveCredentials) {
        $myCreds | Export-Clixml -Path $credsFile
        write-log "credentials saved as $credsFile" -type info
    }
}

get-Credential używa DPAPI i w 'zamkniętym’ środowisq (np. na własnym lapq) w zupełności wystarcza. z tego co kojarzę szyfrowane jest kluczem użytkownika i komputera więc taki plik, aby był odczytany, musi być w tym samym środowisq. mimo wszystko w 'otwartym’ środowisq raczej nie należy stosować takich metod.

eN.

 

wygaszanie tokenów – zmora bezpieczeństwa i CAEP

Obsługa tokenu w czasie rzeczywistym

wpis dotyczy nowego mechanizmu bezpieczeństwa – Continues Access Evaluation Protocol. bardzo fajnie, że Microsoft w końcu adresuje bardziej życiowe sytuacje dotyczące sesji użytkownika – konkretnie obsługę wymuszenia wygaśnięcia tokenu uwierzytelnienia. obserwując jednak z poziomu wyższego, działania aplikacji, mam obawy, że to nie adresuje najważniejszych bolączek. przekonamy się wkrótce.

ale…. o czym ja mówię?

przykład podany w linkowanym arcie dotyczy wymuszenia wygaśnięcia tokenu bezpieczeństwa np. w przypadq zmiany typu sieci (biurowa/otwarta) w trakcie trwania sesji. w tej chwili token jest przyznawany na 1h i sobie jest póki nie wygaśnie.

ale obserwuję większy problem. 1h nie brzmi jak problem – ale już 2 dni? z praktyki i obserwacji tak właśnie to wygląda – użytkownicy, którzy zostali zablokowani lub wyłączeni często mają dostęp do danych nawet przez kilka dni. na to ile de facto to będzie czasu, wpływa wiele czynników:

  • czy środowisko jest cloud-only czy hybryda
  • jeśli hybryda to w jakim trybie – PHS, PTA czy ADFS? każdy z mechanizmów zmienia przebieg procesu uwierzytelniania i znacząco zmienia wiele aspektów związanych z bezpieczeństwem tożsamości.
  • pośrednio konfiguracja Conditional Access
  • wykorzystanie Cloud App Security – który podobnie do CAEP ma na celu kontrolę sesji a nie warunków dostępu
  • system operacyjny na końcówce – iOS, Android, Windows… na każdym apki zachowują się nieco inaczej
  • inne ustawienia typu konfiguracja serwera MFA w AAD ile czasu może być cache’owany.

w efekcie miałem okazję obserwować sytuacje, w których użytkownik jeszcze przez kilka dni (sic!) miał dostęp do swojego maila. tak – mógł odbierać i wiadomości. póty, póki nie zabił aplikacji na urządzeniu – dopiero wtedy pojawiło się żądanie uwierzytelnienia.

jest nadzieja, że ta oddolna zmiana opisuje tylko część konsekwencji ale w rezultacie zaadresuje ten problem – zwłaszcza, że pierwszymi klientami, które dostaną update jest Outlook i Teams.

procedury w przypadkach krytycznych

jest (teoretyczna) możliwość zabicia wszystkich sesji użytkownika i zmuszenia go do odświeżenia tokenu. jest również możliwość wyczyszczenia danych na końcówkach.

wipe-out

wyczyszczenie danych na końcówce jest możliwe jedynie jeśli zarządzane są aplikacje lub stacja – scenariusze BYOD z managed apps oraz klasyczny MDM z tzw. 'enrollmentem’ urządzeń. odpowiednik 'dodania do domeny’ pod kontrolę InTune (lub innego MDM) do zarządzania końcówką. wtedy zależnie od scenariusza (managed apps/MDM) możemy z portalu Azure wymusić wyczyszczenie danych firmowych (managed apps) lub całego urządzenia (MDM).

warunkiem jest oczywiście, że urządzenie zarejestruje się do sieci, co w przypadq świadomej kradzieży w celu pozyskania danych nie jest oczywiście dużym pocieszeniem. warto również pamiętać, że to już podlega licencjom InTune.

reset sesji

ciekawszym i bardziej powszechnym scenariuszem jest reset sesji użytkownika. po co? uwierzytelnienie jest 'bramą’ którą jak się przekroczy, mamy określony czas przebywania (sesję). do tego należy dodać różne mechanizmy cache – obecne zwłaszcza w aplikacjach mobilnych, ze względu na … mobilność. czyli częste utraty sieci i zmiany punktów dostępowych. pomimo, że token uwierzytelniania żyje 1h, to sesja utrzymywana jest, aż do zerwania albo jakiegoś timeoutu w aplikacji. dla Outlook obserwowałem długie czasy, sięgające nawet 2 dni [dodam, że taki scenariusz miałem ok roq temu – to o tyle istotne, że przy obecnej szybkości zmian, nie do końca wiadomo co jest aktualne. nie robiłem testów ostatnio].

(teoretyczny) reset sesji można wykonać na 3 sposoby. czy też może w 3ech krokach? bo nie jest dla mnie oczywiste w których częściach te kroki się pokrywają a w których wymagają wykonania oddzielnie [zapraszam do komentarzy i wrzucenia linqw – jeśli ktoś posiada materiały wyjaśniające te 'detale’, a jakże istotne ze względu na bezpieczeństwo].

  • z interfejsu AAD, w części 'Authentication Methods’ – opcja 'Revoke MFA sessions’
  • z PowerShell Revoke-AzureADUserAllRefreshToken, który zgodnie z opisem 'unieważnia wszystkie tokeny wydane dla aplikacji użytkownika’
  • z portalu M365 Admin Center – wyszukując użytkownika, w zakładce… OneDrive. tam dostępna jest opcja, która obecnie opisana jest 'Sign-out of all Office 365 sessions’

historycznie opcja 'sign-out user sessions’ działała tylko dla OD właśnie. czy dziś, zostając w tym samym miejscu w interfejsie, zrywa faktycznie sesje? podam taki przykład świeży, z przed miesiąca:

wraz z końcem miesiąca, zakończyło pracę sporo osób pracujących w projekcie i z dostępami administracyjnymi. ok. 3 dni później zgłasza się do mnie jedna z osób z pytaniem, czemu osoba, która już nie powinna być w organizacji 'świeci się w Teams na zielono’ – czyli jest jako aktywna. konto zablokowane, wszelkie resety porobione. nie pomaga. mija kolejny dzień – nadal 'active’. zakładam ticket w MS Support, jakaś tam analiza logów, że user zablokowany, że na pewno nie może się dostać – generalnie nic, czego bym nie wiedział. odpowiedzi na to, czemu sesja jest widoczna jako 'active’ i jak taką sesję zabić – brak. w tej sytuacji nie było zagrożenia, bo faktycznie wszystko było poblokowane i potwierdzały to logi dostępowe, ale ogólnie… brak narzędzi pozwalających na jakąkolwiek kontrolę sesji użytkowników to spory problem chmury. pozostawia sporo niejasności, co w kontekście bezpieczeństwa nie jest pożądane.

liczę na to, że implementacja CAEP znacząco poprawi element kontroli sesji….

eN.

krótkie URLe…

…zniknęły.

nie wczoraj, a pół roq temu, ale może komuś umknęło to tak, jak mi. chodzi o skrócone adresy URL, które dostępne były w różnych serwisach typu OneDrive czy Google Maps. z jednej strony co za różnica czy adres jest skrócony, przecież i tak się go nie uczymy na pamięć, tylko wysyłamy mailem czy innym medium, z drugiej strony miało to ciekawy efekt psychologiczny – taki krótki adres nie straszy. kiedy widzi się długi ciąg znaków w adresie, który mamy kliknąć to budzi niepoqj, w przeciwieństwie do krótkiego, zwięzłego. no i mimo wszystko, rzadko-bo-rzadko, ale czasem taki adres trzeba przedyktować przez telefon. dziwne przypadki się zdarzają.

zastanawiałem się, czemu serwisy Google czy MS wycofały tą usługę i okazuje się, że chodzi o bezpieczeństwo. jeśli udostępnialiście kiedyś pliki lub lokalizacje z usługi chmurowej, to wiecie, że całe bezpieczeństwo opiera się w właśnie na linq – w nim zawarty jest token, upoważniający do edycji lub odczytu pliq. to samo w sobie nie jest jeszcze tragedią, bo wysyłając link mailem musimy pamiętać, że może kiedyś trafić 'gdziekolwiek’ i doqment/lokalizacja będzie mógł być pobrany lub edytowany przez przypadkową osobę. większym problemem był fakt, że token w zawartym linq, oraz uporządkowana struktura serwisu pozwala na dostęp do innych danych.

całość, wraz z raportem na podstawie odkodowanych linqw można znaleźć w tym artyqle a dla leniwych, skrócona wersja przykładowych scenariuszy ataq:

  • dla OneDrive, znalezienie katalogu z zapisem, umożliwia łatwe wstrzyknięcie wirusa/malware na komputery użytkownika, ponieważ usługa ta daje możliwość synchronizacji katalogu, która jest powszechnie wykorzystywana. statystyki z badania pokazały, że aż 7% katalogów dawało możliwość zapisu [SIC!]
  • dla GMaps, wykrycie zapisanych przez użytkownika miejsc, daje możliwość bardzo dokładnego profilowania – w skrócie dostęp do informacji kim jesteśmy, gdzie bywamy, a nawet z kim się spotykamy – co daje podstawy do bardzo dobrze sprofilowanego ataku – czy to elektronicznego, czy IRL.

to w sumie oczywiste, ale przypomina, jak olbrzymia odpowiedzialność spoczywa na dostawcach usług globalnych. taki mały niuansik – ot, skrócony link…

w epoce 'chmury’ i wszechobecnego ułatwiania sobie życia, czasem zapominamy jak niebezpieczne jest udostępnianie danych. nie jestem zwolennikiem paranoidalnego odcinania się od usług… bo są wygodne. i dużo traci się na blokowaniu wszelkich ciasteczek, korzystania z map, backupu zdjęć czy trzymania doqmentów w chmurze. poszukiwanie niszowych rozwiązań, które są rzadziej kierunkiem ataq ze względu na mniejszą popularność, może być jakimś rozwiązaniem. ale traci się wtedy na integracji – decydując się na usługi jednego dostawcy, mamy tzw. 'suite’ czyli cały pakiet usług, pomiędzy którymi łatwo wymienia się dane, co daje olbrzymią elastyczność i wygodę.

wybór należy do Ciebie – byle świadomy!

eN.

SecureString

Windows_PowerShell_iconscenariusz użycia

używanie SecureStringów w PS jest poniekąd wymuszone – w taki sposób przechowywane są hasła, np. w credentialsach:

PS C:\_ScriptZ> $cred=Get-Credential

cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential
PS C:\_ScriptZ> $cred|gm


   TypeName: System.Management.Automation.PSCredential

Name                 MemberType Definition
----                 ---------- ----------
Equals               Method     bool Equals(System.Object obj)
GetHashCode          Method     int GetHashCode()
GetNetworkCredential Method     System.Net.NetworkCredential GetNetworkCredential()
GetObjectData        Method     void GetObjectData(System.Runtime.Serialization.SerializationInfo info,
GetType              Method     type GetType()
ToString             Method     string ToString()
Password             Property   securestring Password {get;}
UserName             Property   string UserName {get;}

SecureString przydaje się do przechowywania haseł, używanych w skryptach – np. skrypt do automatycznego podpięcia licencji office365, który wymaga podania credsów użytkownika z uprawnieniami co najmniej 'User Manager’. można hasło zapisać w pliq jako SS a potem wewnątrz skryptu je odczytać i użyć do złożenia credsów:

PS C:\_ScritpZ>ConvertTo-SecureString -String '<HASLO>' -AsPlainText -Force|ConvertFrom-SecureString|out-file c:\_scriptz\pa.ss

PS C:\_ScriptZ> cat .\pa.ss
01000000d08c9ddf0115d1118c7a00c04fc297eb010000006e58e62b318004439a915f2500cbb1c20000000002000000000003660000c0000000100
00000de193527adebd1535b4b243a2dda67de0000000004800000a000000010000000c6781a7fe77fce164d1fcaa0fc68c30f10000000210bc43ae2
3f49acfb0eae607c0b48341400000043264bf254fc25798b847e94d9ea7ea678051bb2

PS C:\_ScritpZ>$ssPassword=Get-Content c:\_scriptz\pa.ss|ConvertTo-SecureString

PS C:\_ScritpZ>$oCreds=New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "usermanager@w-files.onmicrosoft.com",$ssPassword

bezpieczeństwo SS

rodzą się natychmiast pytania o bezpieczeństwo SecureString – czy takie hasło da się odszyfrować i jak łatwo? hasło jest szyfrowane kluczem, który generowany jest na podstawie hasła użytkownika, a masterkey jest przechowywany na komputerze lokalnym. odpowiedzialne jest za to DPAPI – tutaj znajdziecie więcej informacji. klucz jest przechowywany w $env:USERPROFILE\Application Data\Microsoft\Protect\<GUID>. w efekcie

  • plik jest nie do odczytania na innej maszynie
  • plik jest nie do odczytania przez innego użytkownika

czyli nic da 'wykradzenie’ pliq lub użycie go w kontexcie innego użytkownika.

są potencjalnie metody potrafiące złamać klucz [np. hawkeye inject], ale nie znalazłem praktycznego opisu i na pewno nie są to metody na poziomie script kiddie. można zatem uznać, że jest to świetne narzędzie dla skryptów, które wymagają podania hasła.

addendum

na koniec – jak  odczytać hasło zapisane jako SS? podam dwie metody – dla devów i dla opsów (;

dla devów:

PS C:\_ScriptZ> $ss=cat .\pa.ss|ConvertTo-SecureString
PS C:\_ScriptZ> [System.Runtime.InteropServices.marshal]::PtrToStringAuto([System.Runtime.InteropServices.marshal]::SecureStringToBSTR($ss))
<HASLO>

dla opsów:

po zbudowaniu obiektu credential z wcześniejszego przykładu, mamy zmienną $creds

PS C:\_ScriptZ> $creds.GetNetworkCredential().password
<HASLO>

eN.

Obronić się przed MiTM

Minęło wiele lat od kiedy napisałem tu ostatni post a do tego temat na (re)debiut już nie jest gorący. Chociaż z drugiej strony nie zdążył jeszcze wystygnąć i w każdej chwili może ponownie wybuchnąć. Ale do rzeczy. Dziesięć miesięcy temu okazało się, że przez pół roku Lenovo raczyło swoich użytkowników certyfikatami umożliwiającymi ataki MiTM (https://www.us-cert.gov/ncas/alerts/TA15-051A). Wiadomo, generalne oburzenie, Chińczycy nas śledzą, na pewno to sprawa służb, teorie spiskowe  i w ogóle koniec świata. Szczerze mówiąc temat spłynął po mnie jak po kaczce, sprawdziłem swój tablet (kupiony w przypływie weny wracając z baru po spotkaniu świąteczno noworoczny) i zapomniałem o temacie. Potem gdzieś pojawił się problem z Dell System Detect i zdalnym wywołaniem kodu, który został załatany przed opublikowaniem dziury (http://tomforb.es/dell-system-detect-rce-vulnerability). To ruszyło mnie trochę bardziej, sprawdzanie kto ma zainstalowane oprogramowanie i usunięcie starych wersji okazało się nie być trzema kliknięciami ale koniec końców temat załatwiony i systemy załatane w kilka godzin.

Niby dwie z pozoru niepowiązane rzeczy a jednak ostatnio okazało się, że niektórzy wolą się uczyć na własnych błędach zamiast na cudzych i Dell obdarzył nas kolejną serią serią wpadek (http://joenord.blogspot.in/2015/11/new-dell-computer-comes-with-edellroot.html,http://www.kb.cert.org/vuls/id/925497) instalując razem ze swoim oprogramowaniem certyfikaty w Trusted Root razem z ich kluczami prywatnymi. Do tej pory jest jeszcze prawie ok. Oprogramowanie potrzebuje coś samo podpisać żeby system się nie burzył przy instalacji, certyfikat jest oznaczony jako nieeskportowalny. Nie jest najgorzej, w końcu to narzędzie systemowe a nie aplikacja pokazujące  reklamy jak w przypadku Lenovo i jesteśmy zadowoleni dopóki nie zauważymy, że nasz kolega ma ten sam certyfikat a ktoś nam powie, że klucz prywatny można wyeksportować na przykład za pomocą mimikatz.

W głowie zaczynają układać się klocki pokazujące bardzo prosty scenariusz ataku:

  1. Eksportujemy certyfikat (patrz link powyżej)
  2. Stawiamy darmowe WiFi z SSID Starbunio i idziemy w pobliże kawiarni
  3. Czekamy na kogoś z laptopem Della kto podłączy się do naszego WiFi i otworzy stronę, którą warto przechwycić
  4. Zmieniamy SSID i miejsce bo w naszym pierwotnym celu są same błyszczące Maci
  5. Bingo, złapaliśmy klienta otwierającego stronę banku. Dla niego wszystko wygląda w porządku, jest https, jest zielona kłódeczka a przeglądarka nie ma żadnych podejrzeń. Dopiero jak gość będzie bardzo dociekliwy to okaże się, że certyfikat uwierzytelniający bank wystawił Dell a nie Verisign. My sobie po drodze cały ruch odszyfrowujemy, podmieniamy numery kont (bo kto to sprawdza w smssach) i jesteśmy szczęśliwi.

Problem pojawia się kiedy zdamy sobie sprawę, że nie tylko my możemy tak zrobić a nasi użytkownicy na pewno nie sprawdzają za każdym razem kto wystawił certyfikat stronie i możemy się założyć, że kwestią czasu jest kiedy wypłyną dane z naszej firmy albo ktoś dostanie karnego na Facebook’u. A co jeśli nie tylko Dell i Lenovo mają problem z certyfikatami? Będziemy czekać na białe kapelusze aż opublikują artykuły i łatać za każdym razem licząc na to, że czarne kapelusze nie wkroczyły jeszcze do akcji? A może pójdziemy o krok dalej i będziemy bardziej proaktywni sprawdzając czy mamy jakiekolwiek podejrzane certyfikaty na naszych komputerach?

Teoria mówi, że żaden certyfikat znajdujący się w Trusted Root Certification Authorities nie powinien mieć klucza prywatnego. Gdzieś daleko od nas jest CA a my jemu ufamy ponieważ znamy klucz publiczny CA pasujący do klucza prywatnego używanego do podpisywania certyfikatów. Tyle teorii, praktyka okazuje się być trochę bardziej brutalna ale o tym później.

Kiedy mamy problem z pomocą przychodzi korporacyjna nowomowa i nagle problem staje się on wyzwaniem, a kto nie lubi wyzwań? Do tego jeszcze można zaprzęgnąć lubianego PowerShell i System Center lubiane … inaczej ;)

Zaczynamy od kawałka banalnego kodu:

foreach($BaseStore in Get-ChildItem cert:\)
{
   Get-ChildItem $BaseStore.PSPath -Exclude "My","Remote Desktop","SMS" |ForEach-Object{
      [array]$comptmp = Get-ChildItem $_.PSPath |Where-Object {
         $_.HasPrivateKey `
         -and $_.Subject -notmatch 'DO_NOT_TRUST_FiddlerRoot' `
         -and $_.Subject -notmatch $env:COMPUTERNAME
      }
   [array]$Compromised += $comptmp
   }
}
if($Compromised.Count -eq 0){
   return "Compliant"
}
else
{
   $output = ($Compromised | Out-String)
   return $output
}

Który przeleci nam po wszystkich dostępnych certificates stores wyłączając z tego:

  • My – certyfikaty użytkownika/komputera
  • Remote Desktop – to chyba nie wymaga tłumaczenia
  • SMS – certyfikaty używane przez klienta SCCM

w tym kroku można się pokusić jeszcze o wyłączenie innych rzeczy (np. certyfikatów klienta SCOM) albo zamianę

Get-ChildItem $BaseStore.PSPath -Exclude "My","Remote Desktop","SMS"

na

Get-ChildItem $BaseStore.PSPath -Include "Root"

żeby zaglądać tylko do Trusted Roots. Na razie trzymajmy się pierwszej wersji żeby zobaczyć co się w ogóle dzieje.

 

Jak już wiemy jakie mamy Certificates Stores to warto do nich zajrzeć i zobaczyć jakie mamy certyfikaty z kluczami prywatnymi

[array]$comptmp = Get-ChildItem $_.PSPath |Where-Object {
     $_.HasPrivateKey `
     -and $_.Subject -notmatch 'DO_NOT_TRUST_FiddlerRoot' `
     -and $_.Subject -notmatch $env:COMPUTERNAME
}

żeby uniknąć szumu wywalamy:

  • certyfikat Fiddlera – jego celem jest robienie MiTM i osoby mające go na komputerach wiedzą co robią
  • certyfikat zawierający z temacie nazwę hosta – tak to ciągle jest niebezpieczne ale wiemy, że ten certyfikat mamy tylko my i ewentualnie ktoś kto go nam wygenerował a nie cały internet. Takie świństwa podrzuca na przykład Skype ze skonfigurowanym Click to call

Reszta to proste działania mające na celu sprawdzenia czy mamy jakiekolwiek podejrzane certyfikaty i podanie ich listę lub potwierdzenie, że komputer jest ok.

 

Kiedy mamy już PowerShell to warto byłoby uruchomić go na wszystkich komputerach i sprawdzić kto ma coś podejrzanego na swojej maszynie. Fajnie byłoby też aby sprawdzanie odbywało się cyklicznie i informowało nas kiedy jest coś nie tak. Tutaj przydaje się SCCM i Compliance Settings.

Tworzymy Configuration Item uruchamiające skrypt i sprawdzające co jest na wyjściu

Configuration item

2015-12-08_21-47-13

Compliance Rules

2015-12-08_21-47-35

Compliance Rule

Potem robimy Configuration Baseline, dodajemy do niego nasz Configuration Item i robimy Deploy na kolekcje użytkowników oraz na kolekcje komputerów (odpowiednio All Users i All Systems). Ostatnie może się wydać trochę dziwne ale jest potrzebne żeby sprawdzić zarówno co mają użytkownicy jak i konto local system. Configuration baseline uruchomiony w kontekście systemu (Deploy na kolekcję komputerów) nie może zajrzeć do certyfikatów użytkowników bo te są trzymane w profilach*, a użytkownicy nie mogą zobaczyć jakie certyfikaty ma konto local system, za to zarówno użytkownik jak i local system mogą sprawdzić zawartość Certificate Store: Local Machine.

*-to nie jest do końca prawda bo można podmontować Hive i dekodować certyfikaty ale są na to prostsze sposoby

Jakby ktoś się pokusił dodatkowo o Remediation script żeby usuwać podejrzane certyfikaty to warto pamiętać, że Local System będzie mógł usuwać certyfikaty zarówno swoje jak o Local Machine a użytkownik będzie mógł usuwać wyłącznie swoje.

Na koniec pozostaje skonfigurowanie alertów, wysyłanie ich do SCOM i workflow do obsługi zdarzeń ale to już temat na osobny wpis.