Skip to content

Instantly share code, notes, and snippets.

@inodee
Created February 11, 2025 22:45
Show Gist options
  • Select an option

  • Save inodee/a708550d1fcec4b5d097311c5c775a9e to your computer and use it in GitHub Desktop.

Select an option

Save inodee/a708550d1fcec4b5d097311c5c775a9e to your computer and use it in GitHub Desktop.

The baseline query

`4662_directory_sync_events`

| eval SubjectUserName=lower(trim(SubjectUserName))  ``` Normalize value ```

| bin _time span=1d AS last_day_seen  ``` 1d unit ```

``` Ingest the current baseline ```
| inputlookup append=1 dcsync_baseline.csv

``` Main aggregation ```
| stats max(last_day_seen) AS last_day_seen by SubjectUserName

``` Remove entries older than 90d to keep baseline 'fresh' and small ```
| where last_day_seen > relative_time(now(), "-90d@d")

``` Determine the account type ```
| eval type=if(match(SubjectUserName, "\$$"), "machine", "user")

``` Re-generate the lookup ``` 
| outputlookup append=0 override_if_empty=0 dcsync_baseline.csv

The detection query

`4662_directory_sync_events`

| eval SubjectUserName=lower(trim(SubjectUserName))  ``` Normalize value ```

| eval type=if(match(SubjectUserName, "\$$"), "machine", "user")  ``` Determine the type (lookup based on two keys) ```

``` Check the baseline ```
| lookup local=1 dcsync_baseline.csv SubjectUserName type OUTPUT last_day_seen

| where isnull(last_day_seen)  ``` Check if new that's a SubjectUserName within the last 90 days ```

``` Enrich with asset DB to check if it's a new DC ```
| eval src=if(match(SubjectUserName, "\$$"), replace(SubjectUserName, "\$$", ""), null())
| lookup local=1 asset_lookup_by_str asset AS src OUTPUT category As asset_category

``` Enrich with identity DB ```
| eval user=if(isnull(src), SubjectUserName, null())
| lookup identity_lookup_expanded identity AS user OUTPUT group AS user_group

``` Filter out if: known, likely newly deployed Domain Controller; OR if user is a known high-priv one (ex.: domain admin) ```
| where (isnotnull(src) AND !match(asset_category, "(?i)domain contr")) OR (isnotnull(user) AND !match(user_group, "(?i)domain admins"))

``` Main aggregation ```
| stats min(_time) AS start_time, max(_time) AS end_time, values(user) AS user, values(src) AS src, values(Computer) AS dest
  BY SubjectUserName type

| eval alert_title="Potential DCSync attack from ".type." account ".SubjectUserName
| eval desc="This is the first time in 90 days the ".type." account ".SubjectUserName." is seen performing AD replication, usually done by DCs or authorized high-privilege accounts."
| eval note="For benign cases, there's no need to apply any exception as it's going to be automatically incorporated in the baseline."
![image](https://gist.github.com/user-attachments/assets/cccc7fb3-3bcf-4d79-bf00-6a8640eaa74b)

More details at https://detect.fyi

@inodee
Copy link
Author

inodee commented Feb 12, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment