Search This Blog

Thursday, November 26, 2009

Credit Card Validation

"""
    Provides functions & Fields for validating credit card numbers
    Thanks to David Shaw for the Luhn Checksum code 
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/172845)
"""

import re        
from django import newforms as forms

import datetime
        
def ValidateLuhnChecksum(number_as_string):
    """ checks to make sure that the card passes a luhn mod-10 checksum """

    sum = 0

    num_digits = len(number_as_string)
    oddeven = num_digits & 1

    for i in range(0, num_digits):
        digit = int(number_as_string[i])

        if not (( i & 1 ) ^ oddeven ):

            digit = digit * 2
        if digit > 9:

            digit = digit - 9

        sum = sum + digit

        
    return ( (sum % 10) == 0 )

# Regex for valid card numbers
CC_PATTERNS = {
    'mastercard':   '^5[12345]([0-9]{14})$',
    'visa':         '^4([0-9]{12,15})$',

}

def ValidateCharacters(number):
    """ Checks to make sure string only contains valid characters """
    return re.compile('^[0-9 ]*$').match(number) != None

        
def StripToNumbers(number):
    """ remove spaces from the number """
    if ValidateCharacters(number):

        result = ''
        rx = re.compile('^[0-9]$')

        for d in number:
            if rx.match(d):

                result += d
        return result
    else:
        raise Exception('Number has invalid digits')

def ValidateDigits(type, number):
    """ Checks to make sure that the Digits match the CC pattern """
    regex = CC_PATTERNS.get(type.lower(), False)

    if regex:
        return re.compile(regex).match(number) != None

    else:
        return False

def ValidateCreditCard(type, number):

    """ Check that a credit card number matches the type and validates the Luhn Checksum """
    type = type.strip().lower()
    if ValidateCharacters(number):

        number = StripToNumbers(number)
        if CC_PATTERNS.has_key(type):

            return ValidateDigits(type, number)
            return ValidateLuhnChecksum(number)

    return False

class CreditCardNumberField(forms.CharField):
    """ A newforms widget for a creditcard number """

    def clean(self, value):
        
        value = forms.CharField.clean(self, value)

        if not ValidateCharacters(value):
            raise forms.ValidationError('Can only contain numbers and spaces.')

        value = StripToNumbers(value)
        if not ValidateLuhnChecksum(value):

            raise forms.ValidationError('Not a valid credit card number.')
        
        return value


class CreditCardExpiryField(forms.CharField):
    """ A newforms widget for a creditcard expiry date """
    def clean(self, value):     
        value = forms.CharField.clean(self, value.strip())

        
        # Just check MM/YY Pattern
        r = re.compile('^([0-9][0-9])/([0-9][0-9])$')
        m = r.match(value)

        if m == None:
            raise forms.ValidationError('Must be in the format MM/YY. i.e. "11/10" for Nov 2010.')

        
        # Check that the month is 1-12
        month = int(m.groups()[0])

        if month < 1 or month > 12:
            raise forms.ValidationError('Month must be in the range 1 - 12.')

        
        # Check that the year is not too far into the future
        year = int(m.groups()[1])

        curr_year = datetime.datetime.now().year % 100

        max_year = curr_year + 10
        if year > max_year or year < curr_year:

            raise forms.ValidationError('Year must be in the range %s - %s.' % (str(curr_year).zfill(2), str(max_year).zfill(2),))

        return value   

# An example Form based on ModelForm.
class PaymentForm(forms.ModelForm):    
    cc_number = creditcards.CreditCardNumberField(required=False)

    cc_expiry = creditcards.CreditCardExpiryField()
   
    class Meta:
        model = Payment 
    
    """

        This function checks that the card number matches the card type.  
        If you don't want to do this, comment out this function.
    """
    def clean(self):

        if self.cleaned_data:
            if len(self.cleaned_data.items()) == len(self.fields):      
                if self.cleaned_data['method'] == 'cc':

                    the_type = self.cleaned_data.get('cc_type', '')

                    number = self.cleaned_data.get('cc_number', '')

                    if not ValidateDigits(the_type, number):
                        raise forms.ValidationError('Card Number is not a valid ' + the_type.upper() + ' card number.')

                    if not self.instance.is_payment_valid():
                        raise forms.ValidationError('Credit card payment could not be processed.  Reason is %s.  Check that card details are correct and try again.  If you still receive this error, check with your financial institution.' % (self.instance.gateway_resptxt))

        return self.cleaned_data

Tuesday, November 3, 2009

Snort

Snort is a versatile, lightweight and very useful intrusion detection system. In this article we will look at Snort as a backup Intrusion Detection System for your enterprise network and see whether it can really scale up to the requirements of your enterprise networks.

Our failure establishes only this,
that our determination to succeed
wasn't strong enough.
--Bovee


The main distribution site for Snort is http://www.snort.org. Snort is distributed under the GNU GPL license by the author Martin Roesch. Snort is a lightweight network IDS, capable of performing real-time traffic analysis and packet logging on IP networks. It can perform protocol analysis, content searching/matching. It can be used to detect a variety of attacks and probes, such as buffer overflows, stealth port scans, CGI attacks, SMB probes, OS fingerprinting attempts, and more. Snort uses a flexible rules language to describe traffic that it should collect or pass, and includes a detection engine utilizing a modular plug-in architecture. Snort has real-time alerting capability as well, incorporating alerting mechanisms for Syslog, user- specified files, a UNIX socket, or WinPopup messages to Windows clients using Samba's smbclient. Snort has three primary uses. It can be used as a straight packet sniffer like tcpdump or as a packet logger that is useful for network traffic debugging. It can also be used as a full blown network intrusion detection system.
Snort logs packets in either tcpdump binary format or in Snort's decoded ASCII format to logging directories that are named based on the IP address of the foreign host.
Plug-ins allow the detection and reporting subsystems to be extended. Available plug-ins include database logging, small fragment detection, portscan detection, and HTTP URI normalization.

The ground that we will be covering with respect to Snort will be
- Snort as a straight packet sniffer like tcpdump.
- Snort as a packet logger. Useful for network traffic debugging etc.
- Snort as a full blown network intrusion detection system.

Compiling and installing Snort
Having downloaded Snort, untar the archive with the following command.
bash# tar -xvzf snort-1.6.3.tar.gz

This should do the trick and get it untarred into a directory snort-1.6.3. Having done this, next on the cards is a dependency check for various libraries and header files that Snort needs. You'll need to ensure that you have the sources for libcap. If not, you can download it from ftp://ftp.ee.lbl.gov/libpcap.tar.Z.
Download the libcap headers and untar the archive using the tar command with the similar switches as mentioned above. Enter the directory and carry out the following steps.
bash# ./configure
bash# make
Though we do not need any of the binaries, this is just a precautionary measure. Now, we'll compile Snort. Change into the directory in which Snort lies and issue the following command.
bash# ./configure --with-libpcap-includes=/path/to/your/libcap/headers
bash# make
bash# make install
Using
Now Snort is installed on your system. Let's start using Snort on your system. We'll start with the basics of using Snort as a Packet Sniffer and a Packet Analyser. Apart from running in a promiscuous mode, we will also discover rules that will help us log alerts to our Snort logs or redirect them to syslog.
Using Snort as a packet sniffer and packet analyzer is a pretty simple process. The man pages are very helpful as far as information regarding using Snort is concerned. Let's basically start with a simple command that makes Snort display all the command switches and then exit.
bash# snort -?

The output of the command is as follows.
-*> Snort! <*-
Version 1.6.3
By Martin Roesch (roesch@clark.net, www.snort.org)
USAGE: snort [-options]
Options:
-A Set alert mode: fast, full, or none (alert file alerts only)
'unsock' enables UNIX socket logging (experimental).
-a Display ARP packets
-b Log packets in tcpdump format (much faster!)
-c Use Rules File
-C Print out payloads with character data only (no hex)
-d Dump the Application Layer
-D Run Snort in background (daemon) mode
-e Display the second layer header info
-F Read BPF filters from file
-g Run snort gid as 'gname' user or uid after initialization
-h Home network =
-i Listen on interface
-l Log to directory
-n Exit after receiving packets
-N Turn off logging (alerts still work)
-o Change the rule testing order to Pass|Alert|Log
-O Obfuscate the logged IP addresses
-p Disable promiscuous mode sniffing
-P set explicit snaplen of packet (default: 1514)
-q Quiet. Don't show banner and status report
-r Read and process tcpdump file
-s Log alert messages to syslog
-S Set rules file variable n equal to value v
-t Chroots process to after initialisaton
-u Run snort uid as 'uname' user (or uid) after initialization
-v Be verbose
-V Show version number
-? Show this information
are standard BPF options, as seen in TCPDump

Let's check out the next command wherein we set Snort to a verbose display of the packets sniffed and analyzed. The '-v' switch elicits a verbose response to Stdout. The '-d' switch elicits dumping the decoded application layer data and while '-e' shows the decoded ethernet headers. The '-i' switch specifies the interface to be monitored for packet analysis. The '-h' switch specifies which class of network packets has to be captured. e.g. - The command given below captures all the packets belonging to the class C internal IP's of the type 192.168.1.*.
freeos:~ # snort -v -d -e -i eth0 -h 192.168.1.0/24

If we wanted to generate alerts, the '-A' switch is of importance to us.
-A - Alert using the specified alert-mode. Valid alert modes include 'fast', 'full', 'none', and 'unsock'. Fast, writes alerts to the default 'alert' file in a single-line, syslog style alert message. Full, writes the alert to the 'alert' file with the full decoded header as well as the alert message. The command will then change to the following.
freeos:~ # snort -v -d -e -i eth0 -h 192.168.1.0/24 -A fast

Instead, if you wanted to send alert messages to the syslog daemon, you could use the '-s' switch instead.
-s - Send alert messages to Syslog. On Linux boxes, they will appear in /var/log/secure or /var/log/messages on many other platforms.
freeos:~ # snort -v -d -e -i eth0 -h 192.168.1.0/24 -s
Until now we haven't seen any actual logging taking place. All the packets sniffed and analyzed were just dumped to your screen. To have Snort dump the packets sniffed and analyzed to your logs, you will use the "-l" switch. That dumps all the data, regarding the packets analysed, to the directory log in the current path. You will have to create this directory. Do not expect Snort to create it at runtime.
freeos:~ # snort -v -d -e -i eth0 -h 192.168.1.0/24 -A full -l ./log
But, there is an inherent drawback to this type of packet analysis and reporting. One of the foremost problems that may be encountered can be visualized as follows. Assuming that you are using Snort on your Gigabit ethernet. The speed at which data will be flowing across the network is too much for your NIC working in promiscous mode. Many packets will be dumped because it may not be possible to keep up the pace of analyzing the large amount of high speed data transfers across your network segment. Thus, instead if using the "-l" switch you should use the "-b" switch. This will log packets in tcpdump format and produce minimal alerts. For example:
freeos:~ # snort -b -i eth0 -A fast -h 192.168.1.0/24 -s -l ./log
In this configuration, Snort has been able to log multiple simultaneous probes and attacks on a 100 Mbps LAN running at a saturation level of approximately 80 Mbps. In this configuration the logs are written in binary format to log in tcpdump format. To read this file back and break out the data in the familiar Snort format, just re-run Snort on the data file with the "-r" option and the other options you would normally use.

freeos:~ # snort -i eth0 -l ./log -h 192.168.1.0/24 -A fast -r ./log/snort-123@1016.log
This command deciphers the tcpdump-formatted log file ./log/snort-0123@1016.log and dumps the output in the normal Snort log format in the ./log directory.

This kind of packet sniffing and analysis causes Snort to log all the packets on your network segment. But what if you wanted to log only certain type of packets. Yes, of course, there is a way out. Snort allows you to define your own rules for packet analysis. Use the '-c' command switch for this.
freeos:~ # snort -b -i eth0 -A fast -h 192.168.1.0/24 -s -l ./log -c ./rules.snort
For various rulesets that could be used along with Snort, take a look at http://www.snort.org/snort_rules.html.
Here ends our look at Snort. Following up will be another article that will help you ascertain the dangers that your system logs are prone to and the security measures you can put into place to prevent tampering of your precious system logs in case of a security breach.

Don't let life discourage you;
Everyone who got where he is
had to begin where he was.
-Richard L Evans

tmpwatch - removes files which haven't been accessed for a period of time

tmpwatch recursively removes files which haven't been accessed for a given number of hours. Normally, it's used to clean up directories which are used for temporary holding space such as /tmp.
When changing directories, tmpwatch is very sensitive to possible race conditions and will exit with an error if one is detected. It does not follow symbolic links in the directories it's cleaning (even if a symbolic link is given as its argument), will not switch filesystems,
 and only removes empty directories and regular files. 
By default, tmpwatch dates files by their atime (access time), not their mtime (modification time). If files aren't being removed when ls -l implies they should be, use ls -u to examine their atime to see if that explains the problem.
If the --atime, --ctime or --mtime options are used in combination, the decision about deleting a file will be based on the maximum of this times.
The hours parameter defines the threshold for removing files. If the file has not been accessed for hours hours, the file is removed. Following this, one or more directories may be given for tmpwatch to clean up.

 

OPTIONS

-u, --atime
Make the decision about deleting a file based on the file's atime (access time). This is the default.
 
-m, --mtime
Make the decision about deleting a file based on the file's mtime (modification time) instead of the atime.
-c, --ctime
Make the decision about deleting a file based on the file's ctime (inode change time) instead of the atime; for directories, make the decision based on the mtime.
-a, --all
Remove all file types, not just regular files and directories.
-d, --nodirs
Do not attempt to remove directories, even if they are empty.
-f, --force
Remove files even if root doesn't have write access (akin to rm -f).
-t, --test
Doesn't remove files, but goes through the motions of removing them. This implies -v.
-s, --fuser
Attempt to use the "fuser" command to see if a file is already open before removing it. Not enabled by default. Does help in some circumstances, but not all. Dependent on fuser being installed in /sbin.
-v, --verbose
Print a verbose display. Two levels of verboseness are available -- use this option twice to get the most verbose output.
 

SEE ALSO

cron(1), ls(1), rm(1), fuser(1)
 
Example:
You may need to use a command called tmpwatch which removes files which haven’t been accessed for a period of time. Normally, it’s used to clean up directories which are used for temporary holding space such as /tmp. Following code will remove all files/dirs from /tmp if they are not accessed in last 2 weeks (24 * 14 days = 336)
Code:
tmpwatch --mtime --all 336 /tmp