Original Article at<span>:</span>https://penafieljlm.wordpress.com/2016/10/29/ekoparty-ctf-2016-write-ups/#web-150Web 150 (Carder)This is the last challenge that I was able to answer in the CTF event. This is a pretty straightforward challenge. You just need to provide three valid credit card numbers to the form presented in the page referred to by the description of the puzzle. You will have to do this in fifteen seconds or less so you have to prepare your “fast hands” game.RequirementsPythonProcessUpon clicking the link presented in the description of the puzzle, you will be taken to a page asking for valid numbers for Visa, Master Card, and American Express credit cards. You have to provide the numbers within 15 seconds. The time frame validation is checked both at the client and server side so you can’t just change the HTML in the page after the time period has expired.The page already provides you with the first and last four digits of the credit card numbers that you need to provide. You just need to fill in the missing numbers in the middle. The next step will be determining how long the missing numbers are. Luckily for us, the form already tells us how many numbers are missing. This detail is important because once we start brute forcing for the appropriate numbers, we need to know how many zeroes we have to pad to our iterator. This will make sense in a while so please bear with me.Create a new Python script file and save it as creditcard.py. This is the file where we’ll be writing our brute force script.Paste the following function into creditcard.py```<span>def cardLuhnChecksumIsValid(card_number):</span><span>    """ checks to make sure that the card passes a luhn mod-10 checksum """    sum = 0    num_digits = len(card_number)    oddeven = num_digits & 1    for count in range(0, num_digits):</span><span>        digit = int(card_number[count])       if not (( count & 1 ) ^ oddeven ):</span><span><span>           digit = digit * 2</span>       if digit > 9:</span><span><span><span><span>           digit = digit - 9</span>       sum = sum + digit</span>    return ( (sum % 10) == 0 ).```</span>See: Python Luhn checksum for credit card validation (Python recipe)</span>The code above essentially returns True if you give it a valid credit card number, and False if you give it an invalid credit card numberNext. we’ll declare a jobs array right after the declaration of the cardLuhnChecksumIsValid function. This will contain the prefix and suffix of the numbers that we need to brute force as well as the length of the missing pieces in between those numbers```# list format: [missing_len, prefix, suffix]jobs = [    [5], [8], [7]]```For each array element in our jobs array, the first element shall be the length of the missing digits of the numbers, the second element shall be the prefix of the numbers provided by the web page, and the third element shall be the suffix of the numbers provided by the web page. I initialise the first element of each array with the length of the missing pieces of the numbers based on the information that we have gathered in step 2. As you can see from the lengths that I have provided, the first array will be representing the Visa number, the second array will be representing the Master Card number, and the third array will be representing the American Express number. I leave out the prefix and suffix fields because we’ll have to take those as inputs from the user. Unfortunately, we can’t just hard code the prefix and suffix values because they change every time you refresh the puzzle’s web page.We will want to be able to quickly provide the prefix and suffix values to the program. Typing them in one by one just won’t do given the 15 seconds time window the puzzle provides us with, so that’s why we will want to be able to highlight and copy the values from the web page and then paste them into the program’s Standard Input. After highlighting the form in the web page, hitting Ctrl+C and pasting into a text editor, I can see that our program will be encountering the data in the following form:```4556rest of your number1231Mastercard5242rest of your number3250American Express3423rest of your number0249```As we can see in the form of the data that we will be providing to our program, we’re going to have to ignore the lines containing rest of your number and the card names.Right after the declaration of the jobs array, add the following lines of code:```index = 0for index in range(0, 10 + 1):    line = raw_input()    if index == 0 or index == 2:        jobs[0].append(line.strip())    if index == 4 or index == 6:        jobs[1].append(line.strip())    if index == 8 or index == 10:        jobs[2].append(line.strip())    index += 1```This will read the prefix of the numbers in lines 0, 4, and 8. Meanwhile, suffix number will be read from lines 2, 6, and 10.Next, we’ll be doing the actual brute forcing of the numbers. Go ahead and paste the following lines of code at the bottom of the segment where we acquire the user’s inputs.```for job in jobs:    length, prefix, suffix = job    for i in range(0, int(math.pow(10, length))):        iteration = str(i).zfill(length)        number = prefix + iteration + suffix    if cardLuhnChecksumIsValid(number):        print iteration        break```So, what we’re doing here is that we go over all the jobs inside of our jobs array, and then for each job, we acquire the length, prefix, and suffix of the current job, and then we iterate over all the numbers in the number space based on the length of the missing digits of the credit card number we are currently brute forcing. For each iteration, we pad our iterator with zeroes until the desired length is reached, and then we formulate the final credit card number to test by prepending and appending the prefix and suffix values respectively. After that, we check if the number is valid by using the cardLuhnChecksumIsValid function. If the credit card number is invalid, we simply move on to the next iteration. If the credit card number is valid, we print the valid onto the Standard Output, and then move on to the next credit card number to brute force.Let’s test our script.The highlighted parts are the output, and the rest is the input pasted from the web page. Make sure you hit the Enter key after pasting the input. The script can usually calculate valid credit card numbers in under 2 seconds. I use a high-end gaming rig so it might be a bit different for you.Copying text from the Command Prompt window is difficult given the time constraint of the puzzle so we would want to have that output somewhere easier to copy from, hence, I piped the program’s output into a text file and opened that file using Notepad. For faster execution, write a batch script like the following:```python creditcard.py > creditcard.txtnotepad creditcard.txt```Now prepare the Doritos and Mountain Dew because we’re gonna be doing some real MLG Quick Scoping action here. If you fail, start from this step again.Run the batch script I asked you to create earlier but don’t do anything yet once creditcard.py has begun executingMake sure that the web browser viewing the puzzle page is windowed. Move it right beside the Command Prompt window that the batch script is executing on. This will allow us to quickly copy from the web page and paste into the creditcard.py script.Now refresh the page and quickly copy the information that we need from the web page like this:After that, quickly paste into the Command Prompt window running the batch script like this. In Windows 10, you just need to right-click. It might be a lot harder in older versions of Windows.Hit enter, and a Notepad window containing the numbers you need will pop up.Now paste those values into the puzzle web page before the timer runs out. Make sure you play your best Eurobeat track while doing this so you can attack those input fields at incredibly high speeds.Once you succeed, you’ll end up with something like the image below. If you fail, do as they say and “git gud“.The flag is EKO{abda121daf4c4a7ba3e765b041a2f186}Download the source code for creditcard.py here