Just a Web Fuzzer Example
Bellow script demonstrate how to create a very basic multithreaded web file and directory fuzzer.
It is far from being as fast as other famous web fuzzers (wfuzz, dirb, gobuster etc..) but it is at least a good start to understand how to create yours.
#!/bin/python3
'''
-= Just a web fuzzer example =-
(@DarkCoderSc)
Dependencies:
- pip install progressbar2
'''
import requests
import progressbar
from multiprocessing import Pool
from multiprocessing.dummy import Pool as ThreadPool
from multiprocessing import Lock
import argparse
#
# Acquire parameters
#
parser = argparse.ArgumentParser(description="Just a web fuzzer example")
parser.add_argument('-u', '--url', action="store", dest="base_url", required=True, help="Target base URL to fuzz (ex: http://example.com/")
parser.add_argument('-w', '--wordlist', action="store", dest="wordlist_file", metavar="in-file", type=argparse.FileType('r'), required=True, help="Plain text wordlist file location.")
parser.add_argument('-x', '--extensions', action="store", dest="extensions", nargs='*', required=False, help="Append file extension at the end of each candidates (ex: .php .php5 .html .html5)")
try:
argv = parser.parse_args()
except IOError:
parser.error()
#
# Log Defs
#
def success(message):
print("[\033[32mOK\033[39m] " + message)
def fail(message):
print("[\033[31mKO\033[39m] " + message)
def debug(message):
print("[\033[33m!!\033[39m] " + message)
#
# Fuzzer
#
def fuzz(args):
lock = args[0]
pbar = args[2]
global base_url
target_url = base_url + args[1]
req = requests.head(target_url)
status = req.status_code
message = "{} - {}".format(status, target_url)
if (status == 200):
success(message)
elif (status != 404):
debug(message)
lock.acquire()
try:
global progress
progress += 1
pbar.update(progress)
finally:
lock.release()
return
base_url = argv.base_url
if not base_url.endswith("/"):
base_url += "/"
with open(argv.wordlist_file.name, "r", errors="ignore") as file:
candidates = file.readlines()
widgets = [
' [', progressbar.Timer(), '] ',
progressbar.Bar(),
' (', progressbar.ETA(), ') ',
]
ext_count = 1
if argv.extensions:
ext_count = len(argv.extensions) +1
pbar = progressbar.ProgressBar(maxval=(len(candidates) * ext_count), widgets=widgets, redirect_stdout=True)
progress = 0
pbar.start()
try:
pool = ThreadPool()
try:
lock = Lock()
for index, candidate in enumerate(candidates):
candidate = candidate.strip()
if not candidate:
continue
pool.map(fuzz, [[lock, candidate, pbar]])
if (ext_count > 1):
for extension in argv.extensions:
pool.map(fuzz, [[lock, (candidate + extension), pbar]])
finally:
pool.close()
pool.join()
finally:
pbar.finish()
Written the Nov. 23, 2020, 10:20 a.m. by Jean-Pierre LESUEUR
Updated: 1 month, 4 weeks ago.