Forum Discussion
RE: How do you identify 'non-privileged' users...
- Jul 19, 2021Hey Jason, I believe you could write the logic to query the Watchlist and only add new members but believe it would be easier to just load everyone each time, and then query your Watchlist on the same frequency as your Logic App. For example – if you add 10 members on the first run, then add 3 members and run it again 4 hours later, your Watchlist will have 23 total items (original 10, plus 13 – the original 10 again and the new 3), but if you query your Watchlist on items added in the last 4 hours it will only show 13. If you then remove 5 users and run it again 4 hours later, your watchlist will have 31 total items (original 10, then the 13 we added, then the 8 current members), but if you query your Watchlist on the last 4 hours then you will just see the current 8 members and it’s accurate.
Hello m_zorich.
Thank you very much for the reply. It is very much appreciated.
The reason for searching for 'non-privileged' status is to identify those logging onto resources that are short of permissions or privilege. Also the list of privileged users is smaller.
Ideally I want to review the EventID == 4625 from SecurityEvent where I can then 'join' or 'union' those failed user logons (account) against a(n) user (account record) that can identify if they are a privileged user or not.
So for a user (account) entity is there a property that can 'state' if a user has privileged status, OR if they are NOT a member of a privileged access group, OR a member added to a security enabled group (EventIDs in "4728", "4732", or "4756") ?
So a simple starting point for failed logons being:
SecurityEvent
| where TimeGenerated >= ago(1d)
| where EventID == 4625
| summarize FailedLogons=count() by Account, Computer
| sort by FailedLogons desc
I will of course look at your links, but any further feedback to the questions I ask, would be very much welcomed.
Jason
let PrivilegedUsers = (_GetWatchlist('PrivilegedUsers') | project Account);
SecurityEvent
| where TimeGenerated >= ago(1d)
| where EventID == 4625
| where Account !in (PrivilegedUsers)
| summarize FailedLogons=count() by Account, Computer
| sort by FailedLogons desc
You could do the same for group membership changes, create a Watchlist called PrivilegedGroups with TargetAccount as the column header, then the list of names of the groups you want to monitor, then your query will be
let PrivilegedGroups = (_GetWatchlist('PrivilegedGroups') | project TargetAccount);
SecurityEvent
| where EventID in (4728, 4732, 4756)
| where TargetAccount in (PrivilegedGroups)
You can combine the two as well, so something like
let PrivilegedGroups = (_GetWatchlist('PrivilegedGroups') | project TargetAccount);
let PrivilegedUsers = (_GetWatchlist('PrivilegedUsers') | project Account);
SecurityEvent
| where EventID in (4728, 4732, 4756)
| where TargetAccount in (PrivilegedGroups) and Account !in (PrivilegedUsers)
Would give you a non privileged user being added to a privileged group
Instead of watchlists the alternate would be ingest this info as a custom table, PrivilegedGroups_CL and PrivilegedUsers_CL (see the examples in the last post), then you could join & lookup that way. The key will be keeping those lists current.
- JMSHW0420Jul 11, 2021Iron ContributorHello m_zorich.
Thank you for the great response.
Watchlists I understand. Definitely a possibility but the key will be is to understand how to make them dynamic. What I mean is, is there a way to keep them up to date on regular basis, like a TIP (Threat Intelligent Platform/STIX/TAXII) feed?
I will look at the ingesting method from your previous post, so creating a custom table of privileged users. I will keep this post open, in case I run into any issues, if that is OK with you?
The end goal is run this query as an analytics rule that can trigger as an Incident. The trigger would activate a workbook/logic app that could disable the said 'non-privileged' account.
Jason- m_zorichJul 11, 2021Iron ContributorYep sounds good, best of luck with it. The custom table essentially becomes some threat intelligence that is unique to your environment, it won't be in STIX/TAXII format of course but you will still be able to join/lookup against it. If you ingest it say daily to keep it accurate, then when you query that table just look at the last 24 hours of logs to make sure the data is current.
- JMSHW0420Jul 13, 2021Iron ContributorHi again m_zorich,
In regard to ingesting Azure AD information and specifically looking at users as an extension property to Azure Sentinel, are there any extension properties relating to if a user has privileged status or will using an array of sorts with known privileged AAD Group ID’s probably a better way of looking at this?
Using a watchlist is still my preferred solution.
The reason I ask, is because I still clarifying with the end client how a privileged user account is defined and where it is applied.
Jason