I've said it before, I'll say it again: DevCentral is an awesome place to be. Our community is comprised of the best members in the world, and it shows by the way we help each other and care for our collective community. I have a little story to tell (and a solution to share) about the way our community continues to thrive. Earlier this month, DevCentral got hit with a series of unwanted Spam messages...everything from improving love life to black magic potions to astrology secrets. Did these topics catch my interest? Ummm, yeah. Were they appropriate for DevCentral? Probably not. Did we want to get these removed and ensure they never showed up again? Of course. Do I ask myself questions and then answer them myself? Most definitely!
Our site is designed to allow (and encourage) open communication among all our members. While we want everyone to share and collaborate, we obviously discourage malicious or just outright annoying posts on our site. So when we got hit with these spam messages, we quickly deleted them. In fact many of you helped identify and report these as spam messages...so thanks! This is a perfect example of that "caring for our community" stuff I was talking about earlier...good times. While we were able to delete these posts, we wanted a more proactive approach that stopped them before they ever hit our site.
Spam noun \ˈspam\ : irrelevant or inappropriate messages sent on the Internet to a large number of recipients.
As our team thought about different approaches for proactive spam blocking, we considered the trusty BIG-IP Application Security Manager (ASM). If you don't know about all the goodness of the ASM, check out some of my previous articles on this thing...it's amazing and awesome! The ASM comes pre-loaded with ~2,400 attack signatures that block all kinds of malicious activity. It's also flexible enough to allow for custom attack signatures when you run into a unique situations...and this spam situation was a perfect candidate for some custom attack sigs. We needed a way to trigger on a keyword and block any post that included that keyword (or keywords). So, I created a custom attack signature that does just that...it looks for a keyword and blocks any request that has the keyword.
One of the reasons the ASM signature was a good solution was that the spam was hitting us from several different IP addresses. We could have easily blocked an IP, but I'm pretty sure Mr. Spam would have found a quick way around that one. Instead, we decided to block based on the content of the messages being posted.
The first step in solving this problem is to create a custom attack signature. Navigate to Security >> Options >> Application Security >> Attack Signatures >> Attack Signature List and you will see a list of all the attack signatures in the ASM (see the screenshot below). Click the "Create" button at the top right part of the screen.
Now it's time to create the custom signature! The first thing you do is name your custom signature (don't put any spaces in the name). Then, you can fill out an optional description...I like to do this to remind myself what in the world I was doing when I created this thing. If you keep the "Auto Apply New Signatures Configuration After Create" enabled, then the ASM will automatically apply any new custom signature to all active security policies that have signature sets containing this signature. I kept this enabled for the DevCentral signatures so that I didn't have to go back and reconfigure any signature sets after I created new custom signatures. On the "Systems" setting, I selected "Various systems" because this specific signature was not necessarily tied to any unique operating systems, web servers, etc. For "Attack Type" I chose "Other Application Attacks" but I could have chosen any of the Attack Types listed in the dropdown menu...but, the "Other Application Attacks" made the most sense for this custom signature.
The "Rule" is where the meat of the signature is built. The ASM has several different rule options and each one has specific syntax requirements. You can find all the details in the ASM Configuration Guide - Appendix C. I used the "content" rule for my specific signature. The content rule matches when a specified character string is found anywhere in the full content of the request. The string match is case-sensitive, and it must be exact. For example, if you choose content "keyword" then it will not match on "key". You can also use the not character (!) in front of the string if you want the rule to match when it does not find the exact string. In addition, a "nocase" modifier is available, and this simply takes away the case-sensitivity of the rule. I used this in my "content" rule because I wanted to make sure I caught all the keywords regardless of their character case.
Here are a few of the rule options available for creating custom signatures:
content: matches when a specified character string is found anywhere in the full content of the request uricontent: matches when the specified string is found anywhere in the normalized URI, including the query string headercontent: matches when the specified string is found anywhere in the HTTP request headers valuecontent: matches when the specified string is found anywhere within a specific alpha-numeric parameter pcre: matches if the regular expression found within the slash (/) characters matches
As for the "Accuracy" and "Risk" settings, I didn't worry about those too much because my specific security policy blocks on all attack signatures regardless of Accuracy or Risk settings. If your policy is different, you can certainly change these settings as appropriate.
Congratulations! You just created a custom ASM attack signature. But wait, there's more. After you create the signature, you have to associate it with a "Signature Set". If you remember from your security policy building days, you actually assign Signature Sets to a security policy, not individual signatures. So, the next step is to create a custom Signature Set. You can get to this screen by navigating to Security >> Options >> Application Security >> Attack Signatures >> Attack Signature Sets and then click "Create" for your new custom Signature Set. I chose the "Filter-based" signature set because I wanted the ASM to automatically choose the correct signatures to add to this set based on the filters I selected. That way, if I needed to create a new custom signature, I could simply apply the correct filters and the new custom signature would automatically get added to my Signature Set (and thus my security policy as well). If you don't want the ASM to do all that work, you can select "Manual" for the Type of Signature Set and then you will manually add signatures as appropriate.
For this specific Signature Set, I chose "Other Application Attacks" as my Attack Type and "Various Systems" as my Assigned Systems (you'll notice a resemblance to the settings in the custom signature). I also kept the default settings for Accuracy, Risk, User-Defined, and Update Date (All). If you mess around with these specific settings, be sure to keep the "User-Defined" signatures or else it won't include the beautiful work you just accomplished when creating your custom (User-Defined) attack signature. Once you select all these settings, the ASM will auto-build the list of attack signatures it plans to include in this Signature Set (listed at the bottom of the page). Be sure to check for your custom signature in this list...if it's not there, then go back and check all the settings to ensure you configured everything properly.
Now that the custom signature is built and the Signature Set is configured correctly, the last step is to associate the Signature Set with your security policy. Navigate to Security >> Application Security >> Attack Signatures >> Attack Signatures Configuration and you will see the screenshot listed below. Be sure the correct security policy is listed in the "Current edited policy" list and then simply move the newly-created Signature Set from the Available column to the Assigned column. You also have the option of selecting Learn, Alarm, and/or Block on this page. I checked them all (wanted to make sure I blocked this spammer). In addition, be sure the "Signature Staging" box is not enabled if you want to block with this policy. Then click "Save" at the bottom and, as always with the ASM, be sure you click the "Apply Policy" button on the upper/right part of the screen. Once you do all that, the policy is updated and active and you will be blocking all requests that have "keyword" anywhere in them.
The final step in my exciting journey was to update the ASM blocking page. You can navigate to Security >> Application Security >> Blocking >> Response Pages and you will see the screenshot below. I updated the AJAX response page (our web app uses json content for Question and Answer pages) with a custom response and then tested it to make sure everything was working properly.
Voilà...it worked!! Check out the screenshot below...and send us an email if your post has been incorrectly identified as spam.
Well, that's it. I hope you have enjoyed this spamalicious experience as much as I have. In all seriousness, it's really cool to be a part of DevCentral, and it's also really cool to be able to use awesome F5 technology to keep our community free from annoying spammers. Send me an email or comment below if you have any questions about all this. Until next time, remember that the only good spam is the stuff you buy in a can from Hormel...oh, who am I kidding, that stuff is nasty also.