3 Days Left to Save $400 on SANS Scottsdale 2015
Previous Question | Back to Intrusion Detection FAQ Home

Using Snort to Detect Clear Text Credit Card Numbers

Jim McMillan
November 2009

Introduction

How can we use Snort IDS to detect sensitive information in clear text on our networks? In this FAQ, we will look at some Snort rules designed to detect clear text credit card numbers. With a little understanding of Snort rules, you could possibly use the same theory to detect other types of sensitive information, such as US Social Security Numbers (SSNs).

Before we build the Snort rules, we first need to understand a little about the format of the information we are looking for in our network traffic. Credit Card formats may be a little easier than other information, but it will give us a good idea of how to build Snort rules to detect specific information. Let's take look at the format of four major credit cards.

Credit Card Number Formats

The Visa card format is 16 digits long and starts with a "4". Examples include:

  • 4xxx-xxxx-xxxx-xxxx
  • 4xxx xxxx xxxx xxxx
  • 4xxxxxxxxxxxxxxx

The MasterCard format is 16 digits long and starts with a "5". Examples include:

  • 5xxx-xxxx-xxxx-xxxx
  • 5xxx xxxx xxxx xxxx
  • 5xxxxxxxxxxxxxxx

The Discover card format is 16 digits long and starts with "6011". Examples include:

  • 6011-xxxx-xxxx-xxxx
  • 6011 xxxx xxxx xxxx
  • 6011xxxxxxxxxxxx

The American Express card format is 15 digits long and starts with a "3". Examples include:

  • 3xxx-xxxxxx-xxxxx
  • 3xxx xxxxxx xxxxx
  • 3xxxxxxxxxxxxxx

Snort Rules

alert tcp any any -> any 80 (msg: "HTTP Traffic";)

The basic rule header consists of the following information:

Action Protocol SrcIP SrcPort Direction DestIP DestPort (rule options)

The sample rule above is set to use the alert action when it detects TCP traffic from any source IP on any port to any destination IP on port 80. When this rule is triggered it then writes the message "HTTP Traffic" to our logs. To make a rule more specific, we could add the "content" and the "nocase" rule options. We modify our basic rule with these options to come up with this rule:

alert tcp any any -> any 80 (msg: "Possible Secret Leak";content:"CompanySecret";nocase;)

This rule will write the alert "Possible Secret Leak" to our logs when a host sends traffic to any destination on port 80 containing the case insensitive string "CompanySecret". Knowing this information about writing Snort rules, how do we watch for credit card number formats we've discussed? Given the formats, we could end up with a lot of unique credit card numbers. This is where PCRE comes into the picture.

Perl Compatible Regular Expressions (PCRE)

Snort uses PCRE to help build signature logic and help fine tune rule implementation. To match our credit card patterns, or be specific about any rule pattern, we can use PCRE regular expressions to build our signatures. PCRE regular expressions are explained pretty well on Perl's website. The expressions we will be interested in are:

ExpressionFunction
\dmatch a single digit character.
{n}match the previous character (or expression) exactly n times.
()used for group in a similar as mathematical logic.
\smatch a whitespace character.
|used to alternate between choices (logical or).
?match the previous character (or expression) one or zero times.

Building Snort Rules for Credit Card Detection

Now that we have a format for the information we are looking for, a background on building snort rules and formatting expressions for PCRE, we can build the rules we need to detect clear text credit cards. Let's go through the process to monitor our TCP network traffic for Visa card numbers.

Looking back at the visa card rules, we have to write PCRE to handle:

A 16 digit number starting with a "4", where the number may have a space, dash, or nothing between every four numbers.

Following the PCRE expressions we identified, we come up with the following logic:

Credit Card RequirementPCRE ExpressionResults
Start with a "4"4We have our starting digit.
Then any 3 digits\d{3}We finish our first four digit sequence.
Then a space, dash or nothing(\s|-)?We account for a divider character, or not.
Then any 4 digits\d{4}We add our second set of four digits.
Then a space, dash or nothing(\s|-)?Another divider?
Then any 4 digits\d{4}A third sequence of four digits.
Then a space, dash or nothing(\s|-)?Our last divider?
Then any 4 digits\d{4}The last four digit sequence.

When we combine all of the expressions, the resulting PCRE expression is:

4\d{3}(\s|-)?\d{4}(\s|-)?\d{4}(\s|-)?\d{4}

For our clear text Visa card rule, we use the Snort PCRE rule option combined with the "content", "nocase", "sid" and "rev" rule options. Our final Snort rule will look like:

alert tcp any any <> any any (pcre:"/4\d{3}(\s|-)?\d{4}(\s|-)?\d{4}(\s|-)?\d{4}/"; \

    msg:"VISA card number detected in clear text";content:"visa";nocase;sid:9000000;rev:1;)

This rule will detect any traffic on any port that has the string "Visa" and a correctly formatted visa card number. The "sid" option will assign it a Snort ID number to uniquely identify the rule. You can use www.snortid.com to lookup rule IDs that are being used by Snort. However, this site does not account for rule IDs that have been created outside of the official snort rules (1,000,000 and less reserved for Snort). So be careful when assigning Snort IDs to your custom rules, other companies such as Emerging Threats create rules in addition to the Snort rules. The "rev" option indicates the revision number for the rule.

Now that we have our Visa card rule built, we can easily build the other credit cards rules as follows:

MasterCard
PCRE5\d{3}(\s|-)?\d{4}(\s|-)?\d{4}(\s|-)?\d{4}
Snort Rulealert tcp any any <> any any (pcre:"/5\d{3}(\s|-)?\d{4}(\s|-)?\d{4}(\s|-)?\d{4}/"; \
msg:"MasterCard number detected in clear text";content:"mastercard";nocase;sid:9000001;rev:1;)
Discover Card
PCRE6011(\s|-)?\d{4}(\s|-)?\d{4}(\s|-)?\d{4}
Snort Rulealert tcp any any <> any any (pcre:"/6011(\s|-)?\d{4}(\s|-)?\d{4}(\s|-)?\d{4}/"; \
msg:"Discover card number detected in clear text";content:"discover";nocase;sid:9000002;rev:1;)
American Express Card
PCRE3\d{3}(\s|-)?\d{6}(\s|-)?\d{5}
Snort Rulealert tcp any any <> any any (pcre:"/3\d{3}(\s|-)?\d{6}(\s|-)?\d{5}/"; \
msg:"American Express card number detected in clear text";content:"amex";nocase;sid:9000003;rev:1;)

Now that we have our credit card rules built, we can add them to our rule set for Snort to use.

Resources

merchant-account-services.org (2006, July 03). Verifying credit cards numbers are valid. Retrieved from http://www.merchant-account-services.org/blog/verifying-credit-cards-numbers-are-valid/

Vossen, JP. (2005, May 05). Modifying and writing custom snort ids rules. Retrieved from http://searchsecurity.techtarget.com/tip/0,289483,sid14_gci998669_mem1,00.html

perl.org, . (n.d.). Perl program documentation: perlre. Retrieved from http://perldoc.perl.org/perlre.html

Snort.Org (2009, October 22). Snort users manual 2.8.5. Retrieved from http://www.snort.org/assets/125/snort_manual-2_8_5_1.pdf