{"id":408,"date":"2025-03-20T20:56:17","date_gmt":"2025-03-20T20:56:17","guid":{"rendered":"https:\/\/blog.lottabytes.com\/?p=408"},"modified":"2025-03-20T20:56:17","modified_gmt":"2025-03-20T20:56:17","slug":"wazuh-alerts-hierarchy-and-custom-rules","status":"publish","type":"post","link":"https:\/\/blog.lottabytes.com\/index.php\/2025\/03\/20\/wazuh-alerts-hierarchy-and-custom-rules\/","title":{"rendered":"Wazuh Alerts &#8211; Hierarchy and Custom Rules"},"content":{"rendered":"\n<p>Wazuh provides and extremely valuable view into the security health of your systems.  However, there are times where the default, out-of-the-box rules don&#8217;t work well for you.  There&#8217;s a <a href=\"https:\/\/documentation.wazuh.com\/current\/user-manual\/ruleset\/rules\/custom.html\">nice tutorial on custom rules<\/a> in the Wazuh documentation, however, it wasn&#8217;t apparently clear to me the hierarchical nature of these rules.  As a consequence, when you create a custom rule, you might inadvertently cause a logging blindspot.<\/p>\n\n\n\n<p>I&#8217;ll use the two below alerts as an example to show this hierarchical nature.  As you can see, my test box has two generic detections for a possible trojan in both<em> \/bin\/kill<\/em> and<em> \/usr\/bin\/kill<\/em>.  Both of these are known to be false positives, due to the presence of the \/tmp string in the binary, which is expected. So, how do I disable this alert, just for these binaries?<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"956\" height=\"160\" src=\"https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image.png\" alt=\"\" class=\"wp-image-409\" srcset=\"https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image.png 956w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-300x50.png 300w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-768x129.png 768w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-950x160.png 950w\" sizes=\"auto, (max-width: 956px) 100vw, 956px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Entire Rule Modifications<\/h2>\n\n\n\n<p>Let&#8217;s say that you have a rule that needs to be entirely updated, perhaps to be muted across the environment.  In this case, the <a href=\"https:\/\/documentation.wazuh.com\/current\/user-manual\/ruleset\/rules\/custom.html\">instructions<\/a> on the Wazuh site are perfect.  The workflow goes like this:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Copy rule definition to <em>\/var\/ossec\/etc\/rules\/local_rules.xml, <\/em>retaining the Rule ID.<\/li>\n\n\n\n<li>Update definition of the rule, possibly to change the level.<\/li>\n\n\n\n<li>Add the tag <em>overwrite=&#8221;yes&#8221; <\/em>to save this new configuration.<\/li>\n<\/ul>\n\n\n\n<p><strong>This activity will effectively nullify the previous rule using that ID<\/strong>.  While you &#8220;might&#8221; want to do this based on your circumstances, you <strong>cannot<\/strong> do something like the below as an <span style=\"text-decoration: underline;\">update<\/span> operation.  The below will entirely overwrite the existing configuration for Rule 510, effectively nullifying it.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"99\" src=\"https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-1-1024x99.png\" alt=\"\" class=\"wp-image-410\" srcset=\"https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-1-1024x99.png 1024w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-1-300x29.png 300w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-1-768x75.png 768w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-1.png 1102w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Rule Hierarchy and Updates<\/h2>\n\n\n\n<p>There is however, a better way to make these sort of additive changes by creating a new rule that inherits the configuration of a previous rule.  As shown below, I&#8217;m going to create a new Rule with ID 100002, that only applies to alerts that are generated by Source ID 510.  It will then run a match validation against by new strings to see if this particular alert should be muted.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"116\" src=\"https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-2-1024x116.png\" alt=\"\" class=\"wp-image-411\" srcset=\"https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-2-1024x116.png 1024w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-2-300x34.png 300w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-2-768x87.png 768w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-2.png 1100w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>To test this theory, I&#8217;m only going to mute the alerts for <em>\/usr\/bin\/kill<\/em>, which should mean that <em>\/bin\/kill<\/em> alerts are still delivered.  This will prove that Rule ID 510 is still functioning, while also demonstrating that I have successfully muted it on <em>\/ust\/bin\/kill.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"113\" src=\"https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-3-1024x113.png\" alt=\"\" class=\"wp-image-412\" srcset=\"https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-3-1024x113.png 1024w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-3-300x33.png 300w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-3-768x85.png 768w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-3.png 1105w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>As you can see from the logs, that is exactly what happens!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"338\" src=\"https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-4-1024x338.png\" alt=\"\" class=\"wp-image-416\" srcset=\"https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-4-1024x338.png 1024w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-4-300x99.png 300w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-4-768x253.png 768w, https:\/\/blog.lottabytes.com\/wp-content\/uploads\/2025\/03\/image-4.png 1256w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Wazuh provides and extremely valuable view into the security health of your systems. However, there are times where the default, out-of-the-box rules don&#8217;t work well for you. There&#8217;s a nice tutorial on custom rules in the Wazuh documentation, however, it wasn&#8217;t apparently clear to me the hierarchical nature of these rules. As a consequence, when &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blog.lottabytes.com\/index.php\/2025\/03\/20\/wazuh-alerts-hierarchy-and-custom-rules\/\" class=\"more-link\">Read more<span class=\"screen-reader-text\"> &#8220;Wazuh Alerts &#8211; Hierarchy and Custom Rules&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[101,102,100,103,82,104,99],"class_list":["post-408","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-alerts","tag-criteria","tag-custom-rules","tag-false-positive","tag-logging","tag-mute","tag-wazuh"],"_links":{"self":[{"href":"https:\/\/blog.lottabytes.com\/index.php\/wp-json\/wp\/v2\/posts\/408","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.lottabytes.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.lottabytes.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.lottabytes.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.lottabytes.com\/index.php\/wp-json\/wp\/v2\/comments?post=408"}],"version-history":[{"count":4,"href":"https:\/\/blog.lottabytes.com\/index.php\/wp-json\/wp\/v2\/posts\/408\/revisions"}],"predecessor-version":[{"id":417,"href":"https:\/\/blog.lottabytes.com\/index.php\/wp-json\/wp\/v2\/posts\/408\/revisions\/417"}],"wp:attachment":[{"href":"https:\/\/blog.lottabytes.com\/index.php\/wp-json\/wp\/v2\/media?parent=408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lottabytes.com\/index.php\/wp-json\/wp\/v2\/categories?post=408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lottabytes.com\/index.php\/wp-json\/wp\/v2\/tags?post=408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}