Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions bin/quickfuzz
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ parser.add_argument('--no-failed', dest='nofailed', action='store_true', help='o
parser.add_argument('--no-color', dest='nocolor', action='store_true', help='do not use color highlighting')
parser.add_argument('--retries', type=int, default=-1, help='number of retires if a port is closed (default=infinite)')
parser.add_argument('--ssl', action='store_true', help='use ssl sockets for this port')
parser.add_argument('--ssl-key', default=None, dest='ssl_key', help='use ssl key and pem for ssl connection')
parser.add_argument('--ssl-pem', default=None, dest='ssl_pem', help='usd ssl key and pem for ssl connection')
parser.add_argument('--summary', action='store_true', help='print a summary in the end instead of live data')
parser.add_argument('--threads', type=int, default=1, help='use ssl sockets for this port')
parser.add_argument('--timeout', type=int, default=2, help='time to wait for a response (default=2)')
Expand All @@ -46,8 +48,8 @@ def main():
# Create a fuzzer object
live = not args.summary and not args.json
fuzzer = quickfuzz.Fuzzer(args.ip, args.port, connect_timeout=args.ct, max_retries=args.retries,
no_color=args.nocolor, no_failed=args.nofailed, ssl=args.ssl,
server_timeout=args.timeout, threads=args.threads, verbose=live)
no_color=args.nocolor, no_failed=args.nofailed, ssl=args.ssl, ssl_key=args.ssl_key,
ssl_pem=args.ssl_pem, server_timeout=args.timeout, threads=args.threads, verbose=live)

# Some payloads contain parameters. Here we cann add their corresponding replacements
fuzzer.add_parameter(b'<@:IP:@>', args.ip.encode('utf-8'))
Expand Down
35 changes: 31 additions & 4 deletions quickfuzz/quickfuzz.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class Fuzzer:
other settings like the usage of ssl or the amount of time between requetss.
'''

def __init__(self, ip, port, connect_timeout=2, max_retries=2, no_color=False, no_failed=False, payloads=[], ssl=False, server_timeout=2, threads=5, verbose=False):
def __init__(self, ip, port, connect_timeout=2, max_retries=2, no_color=False, no_failed=False, payloads=[], ssl=False, ssl_key=None, ssl_pem=None, server_timeout=2, threads=5, verbose=False):
'''
Creates a new Fuzzer object.

Expand All @@ -64,6 +64,8 @@ def __init__(self, ip, port, connect_timeout=2, max_retries=2, no_color=False, n
no_olor (bool) Do not colorize outputs
payloads (list[Payload]) Payloads to use for fuzzing
ssl (bool) Using ssl connections
ssl_key (string) Using ssl key for ssl connections
ssl_pem (string) Using ssl certificate for ssl connections
server_timeout (int) Seconds to wait for a server response
threads (int) Number of thrads to use
verbose (bool) Print live data for each payload
Expand All @@ -73,20 +75,39 @@ def __init__(self, ip, port, connect_timeout=2, max_retries=2, no_color=False, n
self.connect_timeout = connect_timeout
self.max_retries = max_retries
self.ssl = ssl
self.ssl_cert_mode = False
self.ssl_cert_error = False
self.server_timeout = server_timeout
self.threads = threads
self.verbose = verbose
self.payloads = payloads
self.no_failed = no_failed
self.parameter_dict = {}

# Each Fuzzer can define its own color scheme, or no colors at all
self.info_color = None if no_color else "white"
self.error_color = None if no_color else "red"
self.success_color = None if no_color else "green"
self.payload_color = None if no_color else "yellow"
self.warning_color = None if no_color else "yellow"

if ssl:
if ssl_pem is not None and ssl_key is None:
if not os.path.isfile(ssl_pem):
termcolor.cprint(f"[-] Certificate file not found!", self.error_color, file=sys.stderr)
sys.exit()
self.ssl_cert_mode = True
elif ssl_key is not None and ssl_pem is not None:
if not os.path.isfile(ssl_pem) or not os.path.isfile(ssl_key):
termcolor.cprint(f"[-] Certificate or key file not found!", self.error_color, file=sys.stderr)
sys.exit()
self.ssl_cert_mode = True
elif ssl_key is not None:
termcolor.cprint(f"[-] Key parameter needs a certificate file!", self.error_color, file=sys.stderr)
sys.exit()

self.ssl_key = ssl_key
self.ssl_pem = ssl_pem


def connect(self, terminate=False):
'''
Expand All @@ -99,16 +120,22 @@ def connect(self, terminate=False):
Returns:
sock (Socket) TCP Socket for the targeted port
'''


sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

if self.ssl:
context = ssl.SSLContext()
if self.ssl_cert_mode:
try:
context.load_cert_chain(self.ssl_pem, self.ssl_key)
except Exception as e:
termcolor.cprint("[-] Loading certificate error! Printing exception:\n" + e, self.error_color, file=sys.stderr)
sys.exit()
context.verify_mode = ssl.CERT_NONE
context.check_hostname = False
sock = context.wrap_socket(sock)

target = (self.ip, self.port)

# If the request is blocked for some reason, we wait some seconds
# and try again, until the connect works or the maximum number of retires is rached
retry_count = 0
Expand Down