""" Full title: Simple Command Fuzzer Author: Paolo Stagno - voidsec@voidsec.com - https://voidsec.com Usage: Provide this script with a target IP and port. It will start sending a raw buffer with length 50. It will then increment the size at every cicle until the target software will crash. """ #/usr/bin/env python import argparse, random, socket, string, sys from termcolor import cprint from time import sleep def str_generator(size=100, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits + string.punctuation): """ Pseudo-random string generator :param size: size of the string to be generated (default = 100) :param chars: charset to be used for the string generation (default: ASCII uppercase, lowercase, digits and punctuation) :return: generated string """ return str("".join(random.choice(chars) for _ in range(size))) parser = argparse.ArgumentParser(prog="SCF.py", description="Simple Command Fuzzer") parser.add_argument("-t", "--target", dest="target", default=None, required=True, help="Remote target server") parser.add_argument("-p", "--port", dest="port", default=None, required=True, type=int, help="Remote target port") parser.add_argument("--treshold", dest="treshold", default=9000, type=int, help="Max bufer length. Once hit, it will switch to another command") parser.add_argument("--timeout", dest="timeout", default=2, type=int, help="Socket timeout. Used to determine if theremote target has crashed") parser.add_argument("--size", dest="size", default=100, type=int, help="buff incrementing size. Every cycle the buff will be incremented of the specified size") args = parser.parse_args() # Commands & PoC Config options commands = ["STATS", "RTIME", "LTIME", "SRUN", "TRUN", "GMON", "GDOG", "KSTET", "GTER", "HTER", "LTER", "KSTAN"] poc_file = open("SCF_PoC.txt", "w") #------------------------------------------- target = args.target port = args.port treshold = args.treshold timeout = args.timeout size = args.size vulnerable = [] treshold_hit = [] cprint("Simple Command Fuzzer (SCF) by VoidSec","magenta") try: for command in commands: buff = str_generator() user_input = "" cprint("\n[>] Testing {} command:".format(command),"blue") while (len(buff)<=treshold): s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.settimeout(timeout) try: s.connect((target,port)) s.recv(1024) #cprint("Sending {} buff with length: {}".format(command, len(buff)), "blue") sys.stdout.write("\r[-] Sending buffer of {} bytes".format(len(buff))) sys.stdout.flush() s.send(command + " " + buff + "\r\n") s.close() except socket.timeout: # If we fail to send new command to the server, we'll assume it is crashed vulnerable.append((command, len(buff)-size, buff)) cprint("\n[+] Crash occured with {} command and buffer length of {}".format(command, len(buff)-size), "green") while (user_input != "C"): cprint("[!] Restart the server, than press [C] to continue:","yellow") user_input=raw_input().upper() break except socket.error as err: cprint("\n{}".format(err),"red") user_input="" while ((user_input != "K") and (user_input != "C") and (user_input != "S")): cprint("[!] Restart the server, than press [C] to continue fuzzing this command, [S] to skip this command or [K] to abort:","yellow") user_input=raw_input().upper() if (user_input.upper() == "K"): sys.exit(1) elif (user_input.upper() == "C"): cprint("{} bytes buffer size was skipped".format(len(buff)-size),"red") pass elif (user_input.upper() == "S"): user_input="" cprint("Do you want to save this crash? [Y/N]","yellow") user_input=raw_input().upper() if(user_input=="Y"): vulnerable.append((command, len(buff)-size, buff)) cprint("[+] Crash occured with {} command and buffer length of {}".format(command, len(buff)-size), "green") cprint("{} command was skipped".format(command),"red") break sleep(1) buff = buff + str_generator(size) if(len(buff)>treshold): treshold_hit.append(command) cprint("\nVulnerable Commands:\n----------------------","green") poc_file.write("Vulnerable Commands:\n----------------------\n") for i in vulnerable: cprint("- {} crashed with {} bytes".format(i[0], i[1]),"white") cprint("PoC: {}\n".format(i[2]),"grey") poc_file.write("- {} crashed with {} bytes\nPoC: {}\n\n".format(i[0], i[1], i[2])) cprint("\nTreshold hit on:\n----------------------","white") poc_file.write("\nTreshold hit on:\n----------------------\n") for i in treshold_hit: cprint("- {}".format(i),"grey") poc_file.write("- {}\n".format(i)) poc_file.close() except KeyboardInterrupt: cprint("Exiting...","red") sys.exit(0)