There comes a time in a pentest that passing a simple argument to an form field just won't reach its intended sink but will be rejected by a filter of some sort along the way. This is usually the case in loosely structured data such as credit card, imei numbers etc where the luhn-10 error detection algorithm is used to discard invalid data from ever reaching the back-end. This is performed with business logic validation against accidental errors as an incentive rather than security in mind.

For an explanation of the Luhn algorithm see http://en.wikipedia.org/wiki/Luhn_algorithm plus sample implementations for a couple of different languages. It also has a python oneliner for checking the validity of a given input against Luhn algorithm, however I hate onliners.

So i devised a couple of really basic python methods that can be used to either calculate the luhn check digit or check the validity of a given string.

[sourcecode lang="python"]

def calc_luhn( cl ):

if ( cl.isdigit() is False):

print 'Invalid input (not all digits)'

return null

else:

sumall = 0

for i in range(0,len(cl)):

d = cl[i]

if ( ( i % 2) == 0 ):

sumall = sumall + int(d)

else:

tba = str(2 * int(d))

if ( len(tba)== 2 ):

sumall = sumall + int(tba[0])

sumall = sumall + int(tba[1])

else:

sumall = sumall + int(tba)

if ( (sumall % 10) == 0 ):

return cl + '0'

else:

luhndigit = 10 - (sumall % 10)

return cl + str(luhndigit)

def check_luhn( cl ):

if (cl!=calc_luhn(cl[:-1])):

return False

else:

return True

[/sourcecode]

The two functions can be used as below:

>>> # Calculate the luhn digit

>>> l = calc_luhn('35478101234567')

>>> print l

354781012345671

>>> # Check for luhn algorithm compliance

>>> c = check_luhn('354781012345671')

>>> print c

True

>>> c = check_luhn('354781012345672')

>>> print c

False

>>>

Hope it helps someone

./Z

## No comments:

## Post a Comment

Note: only a member of this blog may post a comment.