1

So I have been trying to create a simple bruteforce script for a php form (on my own local webserver of course), It essentially works by inputting data into the from an list through a for loop. Here is the problem; if my list is: list = ['a','b','c','d','e','f','g'] and my for loop looks something like this:

for i in list:
   r = request.post(url, values) #posts the values
   if 'id=correct' in open('output.txt').read(): #check if it works
      print("logged in") 
      #if it works, it would print this, if not, 
      #it will retry with the next element in the list

The problem is, this will work for only one letter passwords (as it only cycles through the list once). My question is; how would I get it so that once it cycles through the list once, it will start the for loop again except with two elements from list(ie, aa,ab,ac,ad,ae,ef etc.)

Thanks!

SamBkamp
  • 65
  • 8
  • See answers to this question.https://stackoverflow.com/questions/7074051/what-is-the-best-way-to-generate-all-possible-three-letter-strings Basically all you need to do is generate all 1-n combinations where n is the max length your password field accepts and try them one by one. Don't try printing the results of the map, you'll run out of memory for large values of n. – BoboDarph Oct 26 '18 at 11:26
  • you also probably want to be checking `r.content` for the server response – Sam Mason Oct 26 '18 at 11:28

2 Answers2

2

You can treat this as a base conversion problem by incrementing a number and converting it to base 7 (the length of your list):

def convert(n, lst):
    s = ''
    while True:
        s = lst[n % len(lst)] + s
        if n < len(lst):
            break
        n = n // len(lst) - 1
    return s

so that:

lst = ['a','b','c','d','e','f','g']
print(convert(0, lst))
print(convert(6, lst))
print(convert(7, lst))
print(convert(8, lst))
print(convert(55, lst))
print(convert(56, lst))
print(convert(57, lst))

outputs:

a
g
aa
ab
gg
aaa
aab
blhsing
  • 91,368
  • 6
  • 71
  • 106
1

If I'm understanding correctly, you can use itertools.

import itertools

lst = ['a','b','c','d']
for x in range(1, len(lst)): 
    passwords = list(itertools.product(lst, repeat=x))
    for password in passwords:
        print(''.join(password))
roganjosh
  • 12,594
  • 4
  • 29
  • 46
  • 1
    I think OP is rather looking for something like `itertools.product(lst, repeat=x)` – tobias_k Oct 26 '18 at 11:32
  • @tobias_k I thought that originally, then settled on permutations since it seems the most logical for a brute-force attack? – roganjosh Oct 26 '18 at 11:33
  • 1
    But this will never find the most common password of all, `password`, due to the two `s` – tobias_k Oct 26 '18 at 11:45
  • @tobias_k I think you're probably right on balance, edited thanks :) – roganjosh Oct 26 '18 at 11:51
  • Further, I think the upper bound could be even higher than `len(lst)` (certainly made sense for permutations, though). Maybe just use `itertools.coun` for that. Otherwise it looks fine now. – tobias_k Oct 26 '18 at 11:53
  • 1
    @tobias_k also a valid point, but I wonder if the OP is aware of how quickly this brute-force approach will become untestable with scale. From their starting point, I'm not sure they're really going for an all-out implementation and they should be using other methods if they really want to test this. – roganjosh Oct 26 '18 at 11:54