Custom RT alert: Failed logons within a specific time for a single AD object

Dear all,

our customer has the following requirement: RT Alert needs to be created when a single AD user has 9 failed logons within 5 minutes originating from two member servers (=workstation, server 1 OR server 2).

Therefor we are using the XML as you can see below. But this RT rule runs if 9 different (or maybe same) AD accounts have logon failures within 5 minutes. We do need to modify the rule to set the focus on a single AD account. Any hints?

Thanks!

 

<rule type="REL" version="1.0">
<arguments>
<argument displayname="Event filter" name="Event filter" description="Filter for matching first event." class="Filter">
<value><filter type="EventFilter" version="1.0">

<arguments>

<argument usedefault="false" displayname="Log Name" name="Log Name" description="Windows Event Log name." class="List">
<value>"Security"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="Computer" name="Computer" description="Computer where the events were generated." class="List">
<value>"SERVER2","SERVER1"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="Event Source" name="Event Source" description="Source of the event." class="List">
<value>"*EventLog*","*Security*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="Event Type" name="Event Type" description="Type of event, such as 'Success Audit' or 'Failure Audit'." class="EventType">
<value>"16"</value>
<default description="Any type">"0-4294967295"</default>
<UISection>0</UISection></argument>

<argument usedefault="true" displayname="Category" name="Category" description="Event category, such as 'Logon/Logoff'." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="false" displayname="EventID" name="EventID" description="EventID of the event." class="RangeList">
<value>"4768-4768,4771-4771"</value>
<default description="Any number">"0-4294967295"</default>
</argument>

<argument usedefault="true" displayname="User" name="User" description="User account the event was generated by." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#1" name="IS#1" description="Insertion String #1." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#2" name="IS#2" description="Insertion String #2." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#3" name="IS#3" description="Insertion String #3." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#4" name="IS#4" description="Insertion String #4." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#5" name="IS#5" description="Insertion String #5." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#6" name="IS#6" description="Insertion String #6." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="false" displayname="IS#7" name="IS#7" description="Insertion String #7." class="List">
<value>"*IP address Server1*","*IP address Server2*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#8" name="IS#8" description="Insertion String #8." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#9" name="IS#9" description="Insertion String #9." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#10" name="IS#10" description="Insertion String #10." class="List">
<value>"*IP address Server1*","*IP address Server2*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#11" name="IS#11" description="Insertion String #11." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#12" name="IS#12" description="Insertion String #12." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#13" name="IS#13" description="Insertion String #13." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#14" name="IS#14" description="Insertion String #14." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#15" name="IS#15" description="Insertion String #15." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#16" name="IS#16" description="Insertion String #16." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#17" name="IS#17" description="Insertion String #17." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#18" name="IS#18" description="Insertion String #18." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#19" name="IS#19" description="Insertion String #19." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#20" name="IS#20" description="Insertion String #20." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#21" name="IS#21" description="Insertion String #21." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#22" name="IS#22" description="Insertion String #22." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#23" name="IS#23" description="Insertion String #23." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#24" name="IS#24" description="Insertion String #24." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#25" name="IS#25" description="Insertion String #25." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#26" name="IS#26" description="Insertion String #26." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#27" name="IS#27" description="Insertion String #27." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#28" name="IS#28" description="Insertion String #28." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#29" name="IS#29" description="Insertion String #29." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

<argument usedefault="true" displayname="IS#30" name="IS#30" description="Insertion String #30." class="List">
<value>"*"</value>
<default description="Any string">"*"</default>
</argument>

</arguments>

<body>

in(_DataSourceName, "wi", array(<parameter name="Log Name"/>) ) and
in(Source, "wi", array(<parameter name="Event Source"/>) ) and
(
(
VersionMajor &lt; 6 and
in(AccountName, "wi", array(<parameter name="User"/>) )
) or
VersionMajor=6
) and
in_range(EventType, <parameter name="Event Type"/>) and
in(Computer, "wi", array(<parameter name="Computer"/>) ) and
in(Category, "wi", array(<parameter name="Category"/>) ) and
in_range(EventID, <parameter name="EventID"/> ) and
in(String1, "wi", array(<parameter name="IS#1"/>) ) and
in(String2, "wi", array(<parameter name="IS#2"/>) ) and
in(String3, "wi", array(<parameter name="IS#3"/>) ) and
in(String4, "wi", array(<parameter name="IS#4"/>) ) and
in(String5, "wi", array(<parameter name="IS#5"/>) ) and
in(String6, "wi", array(<parameter name="IS#6"/>) ) and
in(String7, "wi", array(<parameter name="IS#7"/>) ) and
in(String8, "wi", array(<parameter name="IS#8"/>) ) and
in(String9, "wi", array(<parameter name="IS#9"/>) ) and
in(String10, "wi", array(<parameter name="IS#10"/>) ) and
in(String11, "wi", array(<parameter name="IS#11"/>) ) and
in(String12, "wi", array(<parameter name="IS#12"/>) ) and
in(String13, "wi", array(<parameter name="IS#13"/>) ) and
in(String14, "wi", array(<parameter name="IS#14"/>) ) and
in(String15, "wi", array(<parameter name="IS#15"/>) ) and
in(String16, "wi", array(<parameter name="IS#16"/>) ) and
in(String17, "wi", array(<parameter name="IS#17"/>) ) and
in(String18, "wi", array(<parameter name="IS#18"/>) ) and
in(String19, "wi", array(<parameter name="IS#19"/>) ) and
in(String20, "wi", array(<parameter name="IS#20"/>) ) and
in(String21, "wi", array(<parameter name="IS#21"/>) ) and
in(String22, "wi", array(<parameter name="IS#22"/>) ) and
in(String23, "wi", array(<parameter name="IS#23"/>) ) and
in(String24, "wi", array(<parameter name="IS#24"/>) ) and
in(String25, "wi", array(<parameter name="IS#25"/>) ) and
in(String26, "wi", array(<parameter name="IS#26"/>) ) and
in(String27, "wi", array(<parameter name="IS#27"/>) ) and
in(String28, "wi", array(<parameter name="IS#28"/>) ) and
in(String29, "wi", array(<parameter name="IS#29"/>) ) and
in(String30, "wi", array(<parameter name="IS#30"/>) )

</body>

</filter></value>
</argument>
<argument displayname="Time period" name="Time period" description="Time period in which the events occurred." class="DateTimeRange">
<value>"0/00/0 00:05:00"</value>
</argument>
<argument displayname="Threshold" name="Threshold" description="Events threshold." class="Number">
<value>9</value>
</argument>
</arguments>
<prefilter>
<parameter name="Event filter"/>;
</prefilter>
<body>
(<parameter name="Event filter"/>) and
count(select(
<parameter name="Event filter"/>,
<parameter name="Time period"/>)) &gt;= <parameter name="Threshold"/>;
</body>
</rule>

  • Hi Lars,

    The functionality you are looking for is provided by function select_filtered, it is described in official document here: support.quest.com/.../7
    The rule you have posted has the event filter as a parameter, but this is not enough, need additional filtration inside to compare the current user with the user from previous events, like in the example:
    select_filtered(EventID=100, Z.User = User, 10:00)
    Also I recommend to refer to my answer to another question at:
    www.quest.com/.../want-to-create-a-custom-rule-for-failed-logon-of-specific-accounts-with-thresholds
    That rule is based on Multiple Failed Logon rule, and I recommend to start creating your custom threshold rules from it, or at least have it in mind as a working out-of-the-box example.
    Hope this helps.
  • In reply to Igor.Ilyin:

    Thanks Igor! In general i know how "it should work", but i'm not an expert for creating custom rules. I already tried to copy and modify the RT rule "multiple failed logons", but without success.
    Any help is appreciated :-)

    Thanks a lot and best regards,
    Lars
  • In reply to lars_mueller:

    OK, let's then start from the copy of multiple failed logons. Could you try the following one? If it does not work for you could you describe how it does not :)

    <rule type="REL" version="1.0">
    <arguments>
    <argument displayname="Time period" name="Time period" description="Time period in which the events occurred." class="DateTimeRange">
    <value>"00:05:00"</value>
    </argument>
    <argument displayname="Threshold" name="Threshold" description="Events threshold." class="Number">
    <value>9</value>
    </argument>
    <argument displayname="Included Workstations" name="Included_Workstations" class="List" description="A list of workstations to include.">
    <value>"SERVER1","SERVER2"</value>
    </argument>
    </arguments>
    <prefilter>

    EventID = 4625;

    </prefilter>
    <body>
    count(select_filtered(
    Z.EventID = 4625 and (striequ(Z.String8, "0xc000006d") and striequ(Z.String10, "0xc0000064") or
    striequ(Z.String8, "0xc000006d") and striequ(Z.String10, "0xc000006a") ),
    striequ( Z.String6, String6 ) and striequ( Z.String7, String7 ) and in( String14, "wi", array(<parameter name="Included_Workstations"/>) ),
    <parameter name="Time period"></parameter> ))
    &gt;= <parameter name="Threshold"></parameter>

    and empty(select_matches(
    striequ( Z[0].String6, String6 ) and striequ( Z[0].String7, String7 ),
    <parameter name="Time period"></parameter>
    ))
    </body>
    </rule>
  • In reply to Igor.Ilyin:

    Great, Igor!! Thanks a lot, we´ll test it and i´ll let you know the results :-)
  • In reply to lars_mueller:

    Lars, I beg your pardon, the above rule is not correct, I have not test it well. Hold on...
  • In reply to lars_mueller:

    Oh, it was just a semicolon at the end, please try this improved one (based on 4625):
    <rule type="REL" version="1.0">
    <arguments>
    <argument displayname="Time period" name="Time period" description="Time period in which the events occurred." class="DateTimeRange">
    <value>"00:01:00"</value>
    </argument>
    <argument displayname="Threshold" name="Threshold" description="Events threshold." class="Number">
    <value>3</value>
    </argument>
    <argument displayname="Included Workstations" name="Included_Workstations" class="List" description="A list of workstations to include.">
    <value>"SERVER1","SERVER2"</value>
    </argument>
    </arguments>
    <prefilter>
    EventID = 4625;
    </prefilter>
    <body>
    count (select_filtered
    (
    Z.EventID = 4625 and (striequ(Z.String8, "0xc000006d") and striequ(Z.String10, "0xc0000064") or striequ(Z.String8, "0xc000006d") and striequ(Z.String10, "0xc000006a") ),
    striequ( Z.String6, String6 ) and striequ( Z.String7, String7 ) and in( String14, "wi", array(<parameter name="Included_Workstations"/>) ),
    <parameter name="Time period"></parameter>
    )
    ) &gt;= <parameter name="Threshold"></parameter>
    and empty
    (select_matches
    (
    striequ( Z[0].String6, String6 ) and striequ( Z[0].String7, String7 ),
    <parameter name="Time period"></parameter>
    )
    );
    </body>
    </rule>
  • In reply to Igor.Ilyin:

    Great, i´ll try it :-)
  • In reply to lars_mueller:

    Meanwhile I have created the example based on 4768 and 4771, as your original rule. But, there are some concerns. E.g. in 4768 and 4771 events we have no originating member server names SERVER1 or SERVER2. We have IPs as far as I know, and in addition, this information resides in different string numbers. Also, I used only account name from String1 without the domain name since 4771 does not contain it. You can play with it and give your feedback. :)


    <rule type="REL" version="1.0">
    <arguments>
    <argument displayname="Time period" name="Time period" description="Time period in which the events occurred." class="DateTimeRange">
    <value>"00:05:00"</value>
    </argument>
    <argument displayname="Threshold" name="Threshold" description="Events threshold." class="Number">
    <value>9</value>
    </argument>
    <argument displayname="Included Workstations" name="Included_Workstations" class="List" description="A list of workstations to include.">
    <value>"::1","::ffff:10.154.12.144","::ffff:10.154.12.106","::ffff:10.154.12.135","::ffff:10.154.12.149","::ffff:10.154.12.157"</value>
    </argument>
    </arguments>
    <prefilter>

    EventID = 4768 or EventID = 4771;

    </prefilter>
    <body>
    count (select_filtered
    (
    (EventID = 4768 and in( String10, "wi", array(<parameter name="Included_Workstations"/>))) or (EventID = 4771 and in( String7, "wi", array(<parameter name="Included_Workstations"/>))),
    striequ( Z.String1, String1 ),
    <parameter name="Time period"></parameter>
    )
    ) &gt;= <parameter name="Threshold"></parameter>
    and empty
    (select_matches
    (
    striequ( Z[0].String1, String1 ),
    <parameter name="Time period"></parameter>
    )
    );
    </body>
    </rule>
  • In reply to Igor.Ilyin:

    Thanks, i´ll test it :-)
  • In reply to Igor.Ilyin:

    Hi Igor, thanks for your feedback! In general it is working, but i do get alerts for successful logons as well. Is there any chance to audit failure logons only? Thanks!!
  • In reply to Lars.Mueller:

    Hi Lars,
    Let's add Failure Audit type check for the 4768 event (EventID = 4768 and EventType = 16). The rule changes in the following way:

    <rule type="REL" version="1.0">
    <arguments>
    <argument displayname="Time period" name="Time period" description="Time period in which the events occurred." class="DateTimeRange">
    <value>"00:05:00"</value>
    </argument>
    <argument displayname="Threshold" name="Threshold" description="Events threshold." class="Number">
    <value>9</value>
    </argument>
    <argument displayname="Included Workstations" name="Included_Workstations" class="List" description="A list of workstations to include.">
    <value>"::1","::ffff:10.154.12.144","::ffff:10.154.12.106","::ffff:10.154.12.135","::ffff:10.154.12.149","::ffff:10.154.12.157"</value>
    </argument>
    </arguments>
    <prefilter>

    EventID = 4771 or EventID = 4768 and EventType = 16;

    </prefilter>
    <body>
    count (select_filtered
    (
    (EventID = 4768 and EventType = 16 and in( String10, "wi", array(<parameter name="Included_Workstations"/>))) or (EventID = 4771 and in( String7, "wi", array(<parameter name="Included_Workstations"/>))),
    striequ( Z.String1, String1 ),
    <parameter name="Time period"></parameter>
    )
    ) &gt;= <parameter name="Threshold"></parameter>
    and empty
    (select_matches
    (
    striequ( Z[0].String1, String1 ),
    <parameter name="Time period"></parameter>
    )
    );
    </body>
    </rule>
  • In reply to Igor.Ilyin:

    Great Igor, it´s working :-) Thanks!!