Benjamin Delpy/@gentilkiwi’s Brucon workshop on Mimikatz inspired me to resume my work on detecting DCSync usage inside networks.
Here are 2 Suricata rules to detect Active Directory replication traffic between a domain controller and a domain member like a workstation (e.g. not a domain controller):
alert tcp !$DC_SERVERS any -> $DC_SERVERS any (msg:"Mimikatz DRSUAPI"; flow:established,to_server; content:"|05 00 0b|"; depth:3; content:"|35 42 51 e3 06 4b d1 11 ab 04 00 c0 4f c2 dc d2|"; depth:100; flowbits:set,drsuapi; flowbits:noalert; reference:url,blog.didierstevens.com; classtype:policy-violation; sid:1000001; rev:1;) alert tcp !$DC_SERVERS any -> $DC_SERVERS any (msg:"Mimikatz DRSUAPI DsGetNCChanges Request"; flow:established,to_server; flowbits:isset,drsuapi; content:"|05 00 00|"; depth:3; content:"|03 00|"; offset:22; depth:2; reference:url,blog.didierstevens.com; classtype:policy-violation; sid:1000002; rev:1;)
Variable DC_SERVERS should be set to the IP addresses of the domain controllers.
The first rule will set a flowbit (drsuapi) when DCE/RPC traffic is detected to bind to the directory replication interface (DRSUAPI).
The second rule will detect a DCE/RPC DsGetNCChanges request if the flowbit drsuapi is set.
These rules were tested in a test environment with normal traffic between a workstation and a domain controller, and with Mimikatz DCSync traffic. They were not tested in a production network.
[…] Quickpost: Mimikatz DCSync Detection […]
Pingback by Overview of Content Published In October | Didier Stevens — Wednesday 1 November 2017 @ 0:00
Noticed some issues with these rules when testing DCSync in a live enterprise environment – lots of false positives. Not sure if your actual rule was different when you tested, but there’s a syntax issue with the second rule missing the semicolon after “offset:22″. Once this is corrected it eliminated the false positives, but also has a zero hit rate against true positives. This was then corrected by changing the content match from |00 03| to |03 00| – which appears to be the Opnum for DsGetNCChanges. So the corrected 2nd rule might be:
alert tcp !$DC_SERVERS any -> $DC_SERVERS any (msg:”Mimikatz DRSUAPI DsGetNCChanges Request”; flow:established,to_server; flowbits:isset,drsuapi; content:”|05 00 00|”; depth:3; content:”|03 00|”; offset:22; depth:2; reference:url,blog.didierstevens.com; classtype:policy-violation; sid:1000002; rev:2;)
Have had excellent results in the preliminary testing of this modified rule. Look forward to your thoughts and appreciate your work in documenting this.
Comment by Drew Graybeal — Wednesday 29 August 2018 @ 21:19
Hi, thanks a bunch for the rule! There’s a typo in the second rule at “offset:22 depth:2;”, a semi-colon is missing after 22. Cheers
Comment by nico — Tuesday 8 June 2021 @ 11:09
Thank you
Comment by Didier Stevens — Tuesday 8 June 2021 @ 11:32
Hi again 🙂 I believe the second rule should read *content:”|03 00|”* instead of *content:”|00 03|”* (for opnum 3: GetNCChanges, https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-drsr/b63730ac-614c-431c-9501-28d6aca91894)
Comment by nico — Wednesday 23 June 2021 @ 6:39
Didier did you see Nico’s comment?
Comment by Steve Stonebraker — Thursday 1 July 2021 @ 16:00
Yes, I did, but I’m just back from holiday, and am catching up.
Comment by Didier Stevens — Thursday 1 July 2021 @ 22:23
Thanks a lot for your comment Drew, there are indeed bugs in the rule. I’ll fix them.
Comment by Didier Stevens — Wednesday 28 July 2021 @ 20:49