{"id":268,"date":"2025-06-26T03:56:45","date_gmt":"2025-06-26T03:56:45","guid":{"rendered":"https:\/\/epbrtcybersecurityportfolio.xyz\/?p=268"},"modified":"2025-06-26T03:56:45","modified_gmt":"2025-06-26T03:56:45","slug":"snort-writing-rules-2","status":"publish","type":"post","link":"https:\/\/epbrtcybersecurityportfolio.xyz\/?p=268","title":{"rendered":"Snort Writing Rules 2"},"content":{"rendered":"\n<p><strong>Exercise 1<\/strong><br><strong>Task:<\/strong> Develop a new version of the detection rule created in the first lab that identifies the exploit within the payload by applying keyword options such as <code>offset<\/code>, <code>within<\/code>, <code>depth<\/code>, and <code>distance<\/code>.<\/p>\n\n\n\n<p><strong>Instructions:<\/strong><br>Begin by duplicating the rule you previously created in the last exercise. Paste it into a new file to work with a clean version. Make sure to update the <code>sid<\/code> to a new, unique value and reset the <code>rev<\/code> (revision number) to 1. Although it\u2019s not mandatory, updating the <code>msg<\/code> field is encouraged to help distinguish this alert from the earlier version visually. This isn\u2019t strictly required because the <code>sid<\/code> is already unique and is displayed in any alert output.<\/p>\n\n\n\n<p>1) I analyzed raw packet data to determine the precise starting point of a specific payload pattern: the serie of Xs located in the payload . This task focused on calculating the payload offset using hexadecimal interpretation of both IP and TCP headers.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"230\" src=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-103-1024x230.png\" alt=\"\" class=\"wp-image-271\" srcset=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-103-1024x230.png 1024w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-103-300x68.png 300w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-103-768x173.png 768w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-103.png 1315w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The packet began with the hex value <code>4500<\/code>, indicating a 20-byte IP header. Further inspection of the header\u2014specifically the value <code>4500 00d8 bcb2 4000 4006<\/code>\u2014confirmed the use of TCP, as represented by the protocol number 6. Examining the TCP header at offset <code>0x0020<\/code>, I found the value <code>8018<\/code>, where <code>0x80<\/code> corresponds to a TCP header length of 8 (multiplied by 4), resulting in 32 bytes.<\/p>\n\n\n\n<p>By adding the 20-byte IP header to the 32-byte TCP header, I determined the payload begins at byte offset 52, or <code>0x34<\/code> in hexadecimal. Using the<strong> <\/strong><code><strong>tcpdump<\/strong><\/code> output, I identified the line starting at offset <code>0x0030<\/code> and noted that the first byte at <code>0x0034<\/code>\u2014<code>0x58<\/code>\u2014was the beginning of the payload.<\/p>\n\n\n\n<p>We can use this information to write a more accurate and efficient alert now that we know where our Serie of Xs begins. We can add the option offset 0 right after our content:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"75\" src=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-104-1024x75.png\" alt=\"\" class=\"wp-image-272\" srcset=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-104-1024x75.png 1024w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-104-300x22.png 300w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-104-768x57.png 768w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-104-1536x113.png 1536w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-104.png 1589w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Let&#8217;s try and run this alert to make sure it functions as intended.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"55\" src=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-105-1024x55.png\" alt=\"\" class=\"wp-image-273\" srcset=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-105-1024x55.png 1024w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-105-300x16.png 300w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-105-768x41.png 768w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-105.png 1333w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Both Alerts successfully Triggered. <\/p>\n\n\n\n<p>2) I can continue improving my detection rule by optimizing not just where the signature search begins in the payload, but also how far the inspection should go. This optimization involves defining the maximum distance into the payload that the string matching engine will search for the targeted content.<\/p>\n\n\n\n<p>To implement this, I added one or more rule options to constrain the search window. This ensures the matching engine stops looking after a defined number of bytes, which helps minimize unnecessary processing and improves rule efficiency.<\/p>\n\n\n\n<p>To do this, I am going to use the <strong>Depth<\/strong> option which refers to the size or length of a specified content. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"61\" src=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-106-1024x61.png\" alt=\"\" class=\"wp-image-275\" srcset=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-106-1024x61.png 1024w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-106-300x18.png 300w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-106-768x46.png 768w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-106-1536x92.png 1536w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-106.png 1593w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>We added a depth of 13 to our Xs content because we used a string of 13 Xs in our alert content and therefore the minimum amount we can use for our depth option is also 13. <\/p>\n\n\n\n<p>3) The next step in improving the accuracy of my detection rule is taken by targeting specific binary content found within the payload of the exploit. My goal was to define a <code>content<\/code> match that would identify a sequence of binary data located between two known strings\u2014XXXXXX and <code>\/sh<\/code>.<\/p>\n\n\n\n<p>To begin, I used Snort&#8217;s support for binary content matching by enclosing hexadecimal byte sequences within pipe symbols (<code>|<\/code>). For example, a match string like <code>|89 90 1a 2b|<\/code> would correspond to a precise set of bytes in the payload. This level of specificity helps reduce false positives and ensures that my rule only triggers on highly characteristic patterns of the exploit.<\/p>\n\n\n\n<p>The bytes of interest\u2014<code>e8 ed ff bf b8<\/code>\u2014were identified within the packet at a specific payload offset. This additional match was added immediately after the initial <code>XXXXXX...<\/code> content match:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"78\" src=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-107-1024x78.png\" alt=\"\" class=\"wp-image-277\" srcset=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-107-1024x78.png 1024w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-107-300x23.png 300w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-107-768x59.png 768w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-107-1536x117.png 1536w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-107.png 1588w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Let&#8217;s now use the <code>distance<\/code> and <code>within<\/code> modifiers to control how closely Snort looks for a second match relative to the first one. This approach is especially useful when trying to match content that consistently appears a specific number of bytes after another known pattern.<\/p>\n\n\n\n<p>By analysing the hex output of the packet, I identified the relative location of these two key elements in the payload: the string represented by <code>XXXXXX...<\/code> and the binary sequence (<code>e8 ed ff bf b8<\/code>). Although these bytes appeared to be directly after the X\u2019s in the data, I had to account for the fact that the initial content match was set with an <code>offset<\/code> of 0 and a length of 13 characters. This required adjusting the <code>distance<\/code> value accordingly to avoid skipping the binary data or misaligning the match.<\/p>\n\n\n\n<p>Additionally, I calculated the exact length of the binary pattern to determine an appropriate <code>within<\/code> value, ensuring that Snort stops scanning shortly after the desired match.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"93\" src=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-108-1024x93.png\" alt=\"\" class=\"wp-image-281\" srcset=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-108-1024x93.png 1024w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-108-300x27.png 300w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-108-768x70.png 768w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-108-1536x139.png 1536w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-108.png 1597w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>4) Simplify the logic by combining both content elements into a single content match. This approach reduces the number of operations Snort needs to perform, improving performance and clarity.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"592\" height=\"49\" src=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-109.png\" alt=\"\" class=\"wp-image-283\" srcset=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-109.png 592w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-109-300x25.png 300w\" sizes=\"auto, (max-width: 592px) 100vw, 592px\" \/><\/figure>\n\n\n\n<p>Initially, my instinct was to match strings at their starting point. However, I discovered that it&#8217;s equally valid\u2014and often more effective\u2014to match the trailing portion of a string instead.<\/p>\n\n\n\n<p>This realization helped me streamline my rule logic. Since the payload in this case happened to start at offset zero, it was tempting to match from the beginning. But had the payload been preceded by other data, that approach would have failed. By refactoring the rule to focus on the ending portion of the string, I improved its reliability and flexibility in different network conditions.<\/p>\n\n\n\n<p>5) Add offset, within, distance and depth options to try and make this revised rule as efficient as possible<\/p>\n\n\n\n<p>It was about figuring out how to place each piece of the rule so Snort could accurately spot our target pattern in the payload.<\/p>\n\n\n\n<p>Here\u2019s what I figured out:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>We already knew there were 132 X characters in the string, and we\u2019d used 13 of them in a previous rule. That gave us a starting offset of 119 for our match.<\/li>\n\n\n\n<li>Those 13 characters were followed by 5 bytes of binary data. So, I set the <code>depth<\/code> to 18 to capture all of that (13 + 5).<\/li>\n\n\n\n<li>Since the <code>\/2\/sh<\/code> string comes right after the Xs and binary bytes, it needed to be searched immediately after the first content match, which justified using offset 119.<\/li>\n\n\n\n<li>Instead of matching <code>\/2\/sh<\/code> right away as the next content, I added it with a <code>distance: 0<\/code> from the previous match\u2014basically telling Snort to look for it right after.<\/li>\n\n\n\n<li>I also had to make sure <code>Pb\/bin<\/code>, the final part of the payload, was found within 4 bytes after <code>\/2\/sh<\/code>. It turns out it starts 3 bytes later and is 6 bytes long, so I used <code>distance: 3<\/code> and <code>within: 6<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>Once I put all these details together, I ended up with a rule that\u2019s a lot more efficient and accurate than the one I started with. Here\u2019s what the refined rule looks like now:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"121\" src=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-110-1024x121.png\" alt=\"\" class=\"wp-image-285\" srcset=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-110-1024x121.png 1024w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-110-300x36.png 300w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-110-768x91.png 768w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-110-1536x182.png 1536w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-110.png 1588w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>6) In this exercise, I simulated a real-world scenario where my Snort rule\u2014developed through the previous lab steps\u2014had been deployed in a production environment for a while. Unfortunately, despite that setup, someone still managed to exploit the LamanServer, and no alerts were generated. That was a red flag.<\/p>\n\n\n\n<p>To figure out what went wrong, I pulled packet captures of the suspected exploit and used them to test my detection rule inside my Snort lab setup. Specifically, I ran the rule against the <code>02_exploit.pcap<\/code> file.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"54\" src=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-111-1024x54.png\" alt=\"\" class=\"wp-image-287\" srcset=\"https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-111-1024x54.png 1024w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-111-300x16.png 300w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-111-768x40.png 768w, https:\/\/epbrtcybersecurityportfolio.xyz\/wp-content\/uploads\/2025\/06\/image-111.png 1063w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The goal here was to determine why the IDS didn\u2019t pick up the attack. I used all the rules I had built in the previous exercises and evaluated them against the new pcap file to see if they triggered as expected\u2014or if the attacker had changed something just enough to evade detection.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Exercise 1Task: Develop a new version of the detection rule created in the first lab that identifies the exploit within the payload by applying keyword options such as offset, within, depth, and distance. Instructions:Begin by duplicating the rule you previously created in the last exercise. Paste it into a new file to work with a [&hellip;]<\/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":[],"class_list":["post-268","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/epbrtcybersecurityportfolio.xyz\/index.php?rest_route=\/wp\/v2\/posts\/268","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/epbrtcybersecurityportfolio.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/epbrtcybersecurityportfolio.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/epbrtcybersecurityportfolio.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/epbrtcybersecurityportfolio.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=268"}],"version-history":[{"count":5,"href":"https:\/\/epbrtcybersecurityportfolio.xyz\/index.php?rest_route=\/wp\/v2\/posts\/268\/revisions"}],"predecessor-version":[{"id":288,"href":"https:\/\/epbrtcybersecurityportfolio.xyz\/index.php?rest_route=\/wp\/v2\/posts\/268\/revisions\/288"}],"wp:attachment":[{"href":"https:\/\/epbrtcybersecurityportfolio.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=268"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/epbrtcybersecurityportfolio.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=268"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/epbrtcybersecurityportfolio.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=268"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}