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.

 

|Security use case

Kilka dni temu na blogu zaufanatrzeciastrona.pl (całkiem niezły site) pojawił sie taki opis ataku:
https://zaufanatrzeciastrona.pl/post/uwaga-na-nowy-sprytny-atak-na-polskich-internautow/

Impreza zaczeła się, gdy do netu wypłynęło, że atak sie powiódł, do tego stopnia, że jego wynik, dość wnikliwie opisany na wspomnianym blogu, został usunięty po niecałych 24h od ukazania sie:
https://zaufanatrzeciastrona.pl/post/ogromny-wyciek-danych-duzej-polskiej-kancelarii-skutkiem-niedawnych-atakow/

ale mamy inne opisy:
http://cyberprzestepczosc.pl/2015/mamy-pierwszy-wyciek-danych-z-kancelarii-adwokackiej/
http://serwisy.gazetaprawna.pl/orzeczenia/artykuly/892135,znana-kancelaria-prawna-padla-ofiara-hakerow-wyciekly-dane.html

Temat okazał sie dość gruby, bo do klientów kancelarii, która stała sie jego celem należeli min.:  Bank DnB Nord, IBM, Kraft Foods, PGNiG, Raiffeisen, Telekomunikacja Polska, Unilever, KGHM Polska Miedź, ITI  – reszta klietntów tutaj: https://web.archive.org/web/20150717035609/http://dt.com.pl/index.php?mod=klienci&lang=pl

Gównoburzy w necie dodaje smaczku fakt (no… wyczytałem ten fakt w komentarzach), że wspomniana kancelaria reprezentowała tzw.: “frankowiczów” w procesie z bankami.
Tutaj można sobie poczytać w komciach:  https://zaufanatrzeciastrona.pl/post/wiesz-kto-wlamal-sie-kancelarii-100-000-pln-nagrody-czeka

Dla mnie ważne jest, że to pierwszy przypadek, gdy klienci sami widzą  że te hakiery, to rzeczywiście mogą napsuć krwi i rozpoczyna się dyskusja o podniesieniu poziomu bezpieczeństwa.  Chodź należy też zauważyć, ze wspomniany wyżej atak był dość precyzyjnie skierowany, a to nie pozostawia wiele szans na  obrone.
Ten przypadek może służyć za argument w dyskusji z biznesem, żeby wysupłać pare groszy więcej na ogólnie pojęte bezpieczeństwo.

właściciel plików: administrators

UAC_insigniaprodukty eMeSa wykazują się niesamowitą inkoherencją. z jednej strony  genialnością i pomysłowością, po czym trafia się na opcje [lub ich brak] lub mechanizmy, które zaburzają cały obraz. jednym z najbardziej niedopracowanych i kontrowersyjnych mechanizmów jest UAC – User Account Control. dość często na niego przeklinam i trafiłem na kolejny argument, świadczący o tym, że był wymyślany na złość administratorom. a tak na prawdę będzie to połączenie kilq bezsensownych i niewyjaśnialnych zachować systemu.

chodzi konkretnie o własność [ownership] plików zakładanych przez użytkownika, który należy do grupy administratorów lokalnych. czyli praktycznie zawsze – bo któż inny zarządza serwerem? pliki w takim przypadq mają jako właściciela wpisywane… ‘Administrators’ – zamiast konkretnej osoby. dla windows 2oo3 dało się to wyregulować polisą GPO:

“Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options\System objects: Default owner for objects created by members of the Administrators group”

problem polega na tym, że takiego ustawienia nie ma dla systemów w2k8+. w taki czy inny sposób polisę można przywrócić w interfejsie, ale nie ma to znaczenia, ponieważ systemy jej nie respektują. a jest tak ponieważ zespół wdrażający UAC uważał, że jest tak samo genialny i nieomylny jak ten, który zarządził, że metrointerfejs będzie standardem wszędzie, zawsze i bezwzględnie, łącznie z serwerami. można znaleźć KB, które opisuje, że to właśnie ten wspaniały mechanizm zapewnia, że uprawnienia będą automatycznie nadawane na konkretną osobę, ponieważ nie ma tokena administratora.

wszystko by się nawet kleiło, gdyby nie jeden podstawowy fakt – ktoś, kto to wymyślał raczej nigdy nie administrował serwerem pliqw, pozostając w jakiejś sferze teorii. w ogóle poruszanie się po zarządzanym serwerze jest mało wykonalne bez uprawnień admina, więc nie ma innego wyjścia jak UAC obejść – czy to odpalając jakiegoś file managera w trybie ‘run as administrator’, czy to po prostu wyłączając cały mechanizm. pozostaje jeszcze jeden opisywany radośnie przypadek – UAC nie działa przy operacjach zdalnych, przez sieć, więc tu też zawsze będzie ‘owner:administrators’.

jak to obejść? jedyny sposób jaki znam, to utworzenie grupy, która będzie miała pełne uprawnienia do wszystkich pliqw, ale nie będzie w grupie adminów. takie to trochę naciągane, mało wygodne i zastanawiam się, czy kiedykolwiek widziałem zastosowane w praktyce? uważam, że to jest poważne niedociągnięcie w bezpieczeństwie, ponieważ nie daje łatwej metody sprawdzenia kto dany plik/katalog założył. oczywiście, że ownera da się zmienić, więc można polemizować ‘jakież to tam zabezpieczenie’, jednak z doświadczenia mogę powiedzieć – w większości przypadqw poziom wiedzy, ignorancja i lenistwo są na tyle powszechne, że bardzo podstawowe mechanizmy wystarczają aby odpowiedzieć na podstawowe pytania. a przeciw tym na prawdę dobrym, działającym z premedytacją i tak ciężko coś przeciwdziałać. wielokrotnie też miałem przypadek, kiedy nie chodziło o bezpieczeństwo sensus stricte a po prostu zwykłe wyjaśnienie – ‘kto ten katalog/plik utworzył?’.

eN.

 

Zły to świat…

Wiecie doskonale, że zestrzelono samolot pasażerski…oczywiście w takich sytuacjach następuje natychmiastowy szaber kart kredytowych z rozrzuconego bagażu i ciał ofiar. No i to jakoś jeszcze, ledwo bo ledwo, ale mieści się w mojej głowie…To natomiast to, co się dzieje później już przechodzi wszelkie granice przyzwoitości.

Cytuję za Niebezpiecznik.pl

“…W przypadku MH17 ataki phishing ułatwiają pełne dane wszystkich pasażerów lotu MH17, które zostały opublikowane przez Malezyjskie linie lotnicze. Dzięki nim phisherzy mogą odnaleźć rodziny ofiar w mediach społecznościowych i rozpocząć ukierunkowane ataki (np. podając się za urzędników, wyciągając dodatkowe dane pod pretekstem zasiłków pogrzebowych lub wyłudzając fundusze pod pretekstem opłat dotyczących organizacji pochówku/transportu na miejsce katastrofy)…”

raport uprawnień w AD

podczas audytu AD warto przejrzeć gdzie, kto i co  może. pisałem jakieś skrypty i inne wynalazki, ale są narzędzia, które można zassać bez napocenia się aż tak bardzo. dwa z nich to:

  • dla tych, którzy chcą sobie tylko pooglądać – LIZA. zaletą jest interfejs pozwalający chodzić sobie po drzewq. jednak do audytów jest niezbyt przydatny – nie filtruje defaultSecurityDescriptors, co znacząco utrudnia wykrycie anomalii.. no i nie ma exportu. niewątpliwie tool bardziej administratorski do zapytań typu: “gdzie ma dostęp grupa G?“.
  • fajniejszy jest IMHO ten oto skrypcik w PS. ma wszystko to, co jest potrzebne do analizy – tworzy raporty html/csv, filtruje co trzeba, no i jest w powershellu więc można sobie dokonywać modyfikacji bez konieczności visual studio (;

eN.

Odrobina prywatności na codzień

Temat PRISM powoli się przewala, choć najprawdopodobniej to tylko wierzchołek góry lodowej. Ja trochę się poddałem, bo po kilku latach wykorzystania własnych narzędzi do synchronizacji telefonów, stawiania serwerów do tego celu i ogólnie z góry przegranej walki o prywatność przez przypadek znychronizowałem wszystkie moje skrupulatnie chronione kontakty telefoniczne z kontem gmaila i cała prywatność w pizduuu…

Dla dociekliwych stronka https://prism-break.org przedstawiająca wszelkie “darmowe”, “wolne”, “chroniące prywatność” narzędzia. Ja już chyba jestem za stary na używanie TOR’ów w codziennym życiu, a na forach nie hejtuje, wiec potulnie korzystam z chroma….  ale może ktoś skorzysta z wyszukiwarek mających zastąpić googla… powodzenia.