| Minulý týden jsem potřeboval udělat malý přehled počítačů, ze kterých se jeden určitý uživatel přihlašoval. A vzhledem k tomu, že to je docela zajímavé téma, tak to tu teďka i zveřejním. To se pomějeme :-)
Výpis přihlašovacích událostí
To se jednoduše řekne, ale není to úplně jednoduché. Nejprve si musíme uvědomit, jaké události nás ve skutečnésti zajímají. Ve Windows je možné auditovat dva druhy "přihlašovacích" událostí:
- Account Logon Event - tohle je to, co my budeme hledat. Jedná se o událost ověření příhlašovacích údajů. Tedy buď hesla, nebo třeba čipové karty. Loguje se to tedy pouze na DC (řadičích domény). Tedy samozřejmě i na serverech a stanicích, pokud se použil lokální účet. Tyto události budou dvě. Události od Kerberos ověření, a události od pass-through ověření, jakým je NTLM, nebo Schannel. Od Windows 2008 (a to platí i pro Windows 2012) jsou to čísla událostí 4768 a 4776. Tyto události by mohly mít lepší název. Spíš je to něco jako "authentication event".
- Logon Event - toto nás nezajímá. Jedná se o okamžik vytvoření paměťové struktury access token na počítači, na který jste se "připojili". Buď jste se tam přihlásili lokálně, nebo se tam připojili ze sítě, spustili jste se jako služba, nebo naplánovaná úloha. Lepší název těchto událostí by byl asi "session event".
V případě account logon event událostí nás zajímá pouze vydání TGT tiketu a IP adresa, ze které se o něj požádalo. V případě NTLM a Schannel v něm bude jméno počítače klienta, ze kterého se přistupovalo na nějaký server.
Musíme také prohledat Security protokol na všech DC. Příhlašujete se o libovolné DC, které je živé, takže to není moc jednoduché sjednotit.
Poznámka o jistotě - IP adresa tam bude taková, která je vidět jako zdrojová na tom Kerberos TCP spojení. Pokud to šlo zpoza NATu, tak tam bude ta jeho veřejná adresa. IP adresy se dají samozřejmě i fejknout. Jméno počítače v případě NTLM je také jenom hodně vzdušná informace. To se nijak neověřuje. Jde prostě jen o jméno klienta takové, jaké ho stanice nahlásila. Takže opět tomu věřit na 100% nelze. Ale pro naše účely to úplně stačí.
K výpisu přihlašovacích událostí jsem použil příkaz WEVTUTL. Ten je dostupný až od Windows 2008. Ale zase to má výhodu, že umí vypustit XML formát událostí. Znamená to, že nám skript pojede na všech DC, které jsou alespoň Windows 2008.
Z logu pomocí WEVTUTIL také filtruju pomocí XPath dotazu události pro daného uživatele. To je také mnohem pohodlnější, než vypisovat události přes WMI. Lépe řečeno, pomocí XPath ten dotaz lze udělat, zatímco pomocí WMI nikoliv. S WMI byste museli načíst všechny přihlašovací události obecně a potom to teprve filtrovat v paměti z položky InsertionStrings, což je multihodnota.
Skriptík
Tak tu je výsledek. Jak jsem už říkal, je nutno to spustit na všech DC, ze kterých chcete statistiku
function Measure-LogonStatistics ([string] $userToQuery, [int] $limit)
{
$query = '*[System[band(Keywords,9007199254740992) and ((EventID=4768) or (EventID=4776))] and EventData/Data[@Name=''TargetUserName'']=''{0}'']' -f $userToQuery
$evtXML = wevtutil qe Security /rd:true /f:RenderedXml /c:$limit /e:EVS /q:$query
$xml = [xml] $evtXML
$xml.Evs.Event | % {
$oneEv = $_
[string] $login = ($oneEv.EventData.Data | ? { $_.Name -eq 'TargetUserName' }).'#text'.ToLower().Trim()
[string] $ip = ($oneEv.EventData.Data | ? { $_.Name -eq 'IpAddress' }).'#text'
[string] $wks = ($oneEv.EventData.Data | ? { $_.Name -eq 'Workstation' }).'#text'
if ($ip -ne '') { $comp = $ip.ToLower().Trim() }
if ($wks -ne '') { $comp = $wks.ToLower().Trim() }
if ($comp -like '::ffff:*.*.*.*') { $comp = $comp.SubString(7) }
$oneLogin = New-Object PSCustomObject
$oneLogin | Add-Member -MemberType NoteProperty -Name login -Value $login
$oneLogin | Add-Member -MemberType NoteProperty -Name comp -Value $comp
$oneLogin | Add-Member -MemberType NoteProperty -Name time -Value $oneEv.System.TimeCreated.SystemTime
$oneLogin
}
}
Measure-LogonStatistics 'kamil' 1000 | Select -Unique login, comp
|