Skip to content

Commit

Permalink
2024.3.17:FINALIZATION
Browse files Browse the repository at this point in the history
  • Loading branch information
zinjacoder committed Mar 29, 2024
1 parent 49b9eca commit 20c81c4
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 534 deletions.
62 changes: 35 additions & 27 deletions BrowserBruter.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
{GREEN}### {YELLOW}by Jafar Pathan(@github/zinja-coder) {GREEN}###
{GREEN}### {GREEN}###
{GREEN}### {GREEN}###
{GREEN}### {YELLOW}The First-Ever Advance Browser Based Automated Web Form Fuzzing Tool {GREEN}###
{GREEN}### {YELLOW}The First-Ever! Advance Browser Based Automated Web Form Fuzzing Tool {GREEN}###
{GREEN}### {YELLOW}Version: {BLUE} v2024.3.1 {GREEN}###
{GREEN}### {YELLOW}Github : {BLUE} https://github.com/netsquare/BrowserBruter {GREEN}###
{GREEN}### {GREEN}###
Expand Down Expand Up @@ -111,48 +111,47 @@
args_basic = argParser.add_argument_group("Basic")
args_attack1n2 = argParser.add_argument_group("Sniper and Battering Ram")
args_attack3n4 = argParser.add_argument_group("PitchFork and Cluster Bomb")
args_fuzz = argParser.add_argument_group("Fuzzing and Browser Options")
args_fuzz = argParser.add_argument_group("Fuzzing Options")
args_session = argParser.add_argument_group("Session")
args_javascript = argParser.add_argument_group("JavaScript and Code Handling")
args_javascript = argParser.add_argument_group("JavaScript and Navigation Handling")
args_browser = argParser.add_argument_group("Browser Options")
args_debug = argParser.add_argument_group("Debug Option")
args_report = argParser.add_argument_group("Report Generation")
args_help = argParser.add_argument_group("Help")

# Adding CLI arguments
args_basic.add_argument("--target",help="Target's url: https://zinja-coder.github.io/jafarpathan", metavar="TARGET_URL")
args_basic.add_argument("--button",help="Button element which will submit form data.", metavar="submit")
args_basic.add_argument("--attack",help="The attack mode:\n 1. SNIPER\n 2. BATTERING RAM\n 3. PITCH FORK\n 4. CLUSTER BOMB",type=int,metavar="2")
args_attack1n2.add_argument("--elements", help="Input fields(target elements of form) in comma separated values.", metavar="username,password,phone,address")
args_attack3n4.add_argument("--elements-payloads",help="Input fields(target elements of form) and their respective payloads files.", metavar="FIELD:/PATH/TO/FILE,textarea:payloads.txt,data:pay.txt")
args_attack1n2.add_argument("--payloads",help="/path/to/payload/file.", metavar="/home/payloads.txt")
args_basic.add_argument("-t", "--target",help="Target's url: https://zinja-coder.github.io/jafarpathan", metavar="TARGET_URL")
args_basic.add_argument("-b", "--button",help="Button element which will submit form data.", metavar="submit")
args_basic.add_argument("-a","--attack",help="The attack mode:\n 1. SNIPER\n 2. BATTERING RAM\n 3. PITCH FORK\n 4. CLUSTER BOMB",type=int,metavar="2")
args_attack1n2.add_argument("-e", "--elements", help="Input fields(target elements of form) in comma separated values.", metavar="username,password,phone,address")
args_attack3n4.add_argument("-ep", "--elements-payloads",help="Input fields(target elements of form) and their respective payloads files.", metavar="FIELD:/PATH/TO/FILE,textarea:payloads.txt,data:pay.txt")
args_attack1n2.add_argument("-p", "--payloads",help="/path/to/payload/file.", metavar="/home/payloads.txt")
args_fuzz.add_argument("--fill",help="Auto fill the specified elements, usefull when web page is complex when you want to target specific fields only.",metavar="e1,elemn3,user,npass,id")
args_fuzz.add_argument("--fill-values", help="[Optional] Path to User provided elements values file. See sample-file-for-giving-form-values.json", metavar="/path/to/file.json")
args_fuzz.add_argument("--buttons-to-press-before-fuzz",help="Supply list of buttons to be pressed in sequence before filling the form, useful if form submission requires some action or form is invisible until some button is pressed.[Note if the button is not pressable elment, then use --javascript and suppy javascript to click the element.]",metavar="visibleform,ok,confirm,pressthis")
args_fuzz.add_argument("--press-enter-no-click",help="This switch will force the Browser Bruter to send ENTER key instead of clicking the button, useful when form is submitted when pressing entering on text field and there are no buttons to click.", action="store_true")
args_fuzz.add_argument("--proxy",help="Set proxy for traffic, for example give IP:PORT of Burpsuite to send traffic to burpsuite.",metavar="http://proxyaddress:port/")
args_fuzz.add_argument("--delay-before",help="Delay before fuzz attempt.",metavar="0.2", type=float, default=0.2)
args_fuzz.add_argument("--delay-after",help="Delay after fuzz attempt.",metavar="0.2", type=float, default=0.2)
args_fuzz.add_argument("--threads",help="Specifies number of browsers instances to be run, max value is 5, default is 1, lower the instances slower the fuzzing process, more instances - faster fuzzing process.",metavar="3",default=1, type=int)
args_fuzz.add_argument("--threads",help="Specifies number of browsers instances to be run, max value is 20, default is 1, lower the instances slower and stable the fuzzing process, more instances - faster and unstable fuzzing process. Note: The higher amount of threads consumes more system resources.",metavar="3",default=1, type=int)
args_fuzz.add_argument("--pause", help="Pause the BrowserBruter instances on startup, press ENTER to resume.",action="store_true",default=False)
args_fuzz.add_argument("--interactive",help="Pause the BrowserBruter before fuzzing any element at each payload and wait for user to continue.",action="store_true",default=False)
args_fuzz.add_argument("--pause-after-submit",help="Pause the script after pressing the submit button to allow pentester to interact with the web application.",action="store_true")
args_fuzz.add_argument("--reload-page",help="This switch tells The Browser Bruter to reload the page before fuzzing the form on each iteration, usefull when result of previous iteration causes the web elements to disappear or which leads to elements not found error, in such case this switch helps to keep browser bruter running.", action="store_true")
args_fuzz.add_argument("--form",help="Specy id,name,class of form to fuzz in case of muliple forms",metavar="changePasswordForm")
args_fuzz.add_argument("--ignore-popups",help="Ignore alert and other pop up menus",action="store_true",default=False)
args_fuzz.add_argument("--remove-class",help="Provide a list of elements from which you want to remove the class attribute, extremely useful when element is linked to some class with extreme javascript input validation or makes the element not interactable, you can still select this element by providing it's class name.", metavar="cdk-text-field-autofill-monitored")
args_session.add_argument("--headers", help="Comma-separated list of custom headers.",metavar="\"Auth: 123\",\"CUSTOME_HEADER: VALUE\"")
args_session.add_argument("--headers", help="Comma-separated list of custom headers.",metavar="\"Auth: 123\",\"CUSTOM_HEADER: VALUE\"")
args_session.add_argument("--cookie",help="Use it to define cookies to be used while sending initial request, cookies should be in name:value:domain comma separated format.", metavar="name:value,name2:value2")
args_session.add_argument("--force-cookie",help="Use this switch to force setting of cookies given as argument using --cookie flag regardless of cookies being sent by server.",action="store_true")
args_session.add_argument("--remove-session",help="Use this switch to remove session data and cookies after each request-response cycle.", action="store_true")
args_javascript.add_argument("--auto-remove-javascript-validation",help="This switch will tell The Browser-Bruter to not remove common javascript input validations mechanisms. Useful if removing of javacript validaiton breaks the web app.", action="store_true",default=False)
args_javascript.add_argument("--javascript",help="Javascript code to run on browser", metavar="\"alert(1);\"")
args_javascript.add_argument("--javascript-after",help="Javascriptc code to run on browser after pressing and submitting the button.")
args_javascript.add_argument("--javascript-file",help="Javascritp file containing javascript code to execute", metavar="/path/to/javascript/file.js")
args_javascript.add_argument("--javascript-after",help="Javascript code to run on browser after pressing and submitting the button.")
args_javascript.add_argument("--javascript-file",help="Javascript file containing javascript code to execute", metavar="/path/to/javascript/file.js")
args_javascript.add_argument("--replace-code",help="Replaces the code in response body with the code provided by user in following format - \"CODE_TO_REPLACE1\",\"REPLACEMENT_CODE1\",\"CODE_TO_REPLACE2\",\"REPLACEMENT_CODE2\"",metavar="\"alert(1);\",\"alert(0);\"")
args_javascript.add_argument("--replace-files", help="Replace the content of a file in HTTP responses.", metavar="/path/to/validation_file.js")
args_browser.add_argument("--headless",help="Use this switch to run browser in headless mode (No GUI).", action="store_true")
args_browser.add_argument("--no-css",help="This switch will tell Browser Bruter to drop the requests to .css files and it will load .css files",action="store_true")
args_browser.add_argument("--no-css",help="This switch will tell Browser Bruter to drop the requests to .css files and it will not load .css files and remove <style> tag.",action="store_true")
args_browser.add_argument("--proxy",help="Set proxy for traffic, for example give IP:PORT of Burpsuite to send traffic to burpsuite.",metavar="http://proxyaddress:port/")
args_browser.add_argument("--load-static-media",help="This switch tells BrowserBruter to load audio, video and image (.png, .img, .ico, .mp4, .gif, .mp3 etc) files. By default it discards these files to save time and load pages faster.",action="store_true",default=False)
args_browser.add_argument("--chrome-options",help="Custom comma separated list of options which will be passed to chrome. [This will override in-built options in Browser-Bruter that are passed to chrome]",metavar="blink-settings=imagesEnabled=false,disable-notifications")
args_browser.add_argument("--anti-bot",help="This switch tells BrowserBruter to use avoid any chrome options and use raw undetected chrome driver to avoid bot detection, by default Browser-Bruter uses custom Chrome options along with undetected chrome driver like disabling xss protection along with undeteced chrome driver",action="store_true",default=False)
Expand All @@ -164,7 +163,7 @@
args_report.add_argument("--exclude-urls",help="Comma separated list of urls or file containing urls which are to be excluded from final report", metavar="/path/to/file OR \"http://10.13.37.3:8080/webgoat/service/hint.mvc\",\"http://10.13.37.3:8080/webgoat/service/solution.mvc\"")
args_debug.add_argument("--verbose",help="Use this switch to enable HTTP request/response output being printed on console and STDLOG file.", action="store_true",default=False)
args_debug.add_argument("--debug",help="Use this switch to print the Stack Trace messages in case of the error! and keep the logs in log file.",action="store_true")
args_help.add_argument("--help-manual",help="Print the Usage Exapmles",action="store_true")
args_help.add_argument("--help-manual",help="Print the Usage Examples",action="store_true")

# Getting the arguments in args variable
args = argParser.parse_args()
Expand Down Expand Up @@ -320,6 +319,9 @@
except FileNotFoundError:
print(f"\n\n{RED}[+]--------------------------------------------------------------------------------------------------------------------------[+]\nERROR: {RESET}The specified payloads file '{args.payloads}' does not exist.\n{RED}[+]--------------------------------------------------------------------------------------------------------------------------[+]{RESET}")
sys.exit(0)
else:
print(f"\n\n{RED}[+]--------------------------------------------------------------------------------------------------------------------------[+]\nERROR: {RESET}Please enter values either 1, 2, 3 or 4 in --attack\n{RED}[+]--------------------------------------------------------------------------------------------------------------------------[+]{RESET}")
sys.exit(0)

# Get the content, Replace the response body with the content of the file provided by the user
file_contents = {}
Expand Down Expand Up @@ -399,15 +401,11 @@ def wait_and_handle_popup(driver):
try:
wait.until(EC.presence_of_all_elements_located(("xpath", '//body')))
except UnexpectedAlertPresentException:
#if args.ignore_popups:
try:
alert = driver.switch_to.alert
alert.accept()
except NoAlertPresentException:
pass
#else:
# print(f"\n{YELLOW}[+]--------------------------------------------------------------------------------------------------------------------------[+]\nINFO: {RESET}Alert Pupup please interact with popup or use --ignore-popup option\n{YELLOW}[+]--------------------------------------------------------------------------------------------------------------------------[+]{RESET}")
# input(f"\n{YELLOW}[+]--------------------------------------------------------------------------------------------------------------------------[+]\nINFO: {RESET}press ENTER after intracting with popup\n{YELLOW}[+]--------------------------------------------------------------------------------------------------------------------------[+]{RESET}")

# Handle Unknown Exception
def handle_unknown_exception(exception):
Expand Down Expand Up @@ -479,7 +477,7 @@ def pause_resume():
userText, timeout = timedKey(prompt="", timeout=-1, resetOnInput=True)
if not (timeout):
pause_event.set() # Set the pause event
print(f"\n\n{RED}[+]--------------------------------------------------------------------------------------------------------------------------[+]\nWARNING: {RESET}BROWSERBRUTER IS PAUSED\npress ENTER to resume\nPress y to Enter Interactive Mode\nPress n to Exit Interactive Mode\n{RED}[+]--------------------------------------------------------------------------------------------------------------------------[+]{RESET}")
print(f"\n\n{RED}[+]--------------------------------------------------------------------------------------------------------------------------[+]\nWARNING: {RESET}BROWSERBRUTER IS PAUSED\npress ENTER to resume\nPress y to Enter Interactive Mode\nPress n to Exit Interactive Mode\nPress CTRL+C to exit\n{RED}[+]--------------------------------------------------------------------------------------------------------------------------[+]{RESET}")
k = input()
if k == 'Y' or k == 'y':
args.interactive = True
Expand Down Expand Up @@ -631,7 +629,7 @@ def replace_response_content(request, response):
def get_and_initialize_chrome_driver():
with driver_lock:
options = get_browser_options()
# try to get chrome driver and retry this three times, in case of exceptions, increases the stablility in case of multiples threads
# try to get chrome driver and retry this three times, in case of exceptions, increases the stability in case of multiples threads
try:
if args.no_anti_bot:
service = Service(executable_path="res/chrome/chromedriver")
Expand Down Expand Up @@ -783,7 +781,7 @@ def get_filename():
def handle_new_instance(driver):
driver.quit()
driver = get_and_initialize_chrome_driver()
# Following lines solves the bug in which the --new-instace was not working
# Following lines solves the bug in which the --new-instance was not working
driver.get(args.target)
return driver

Expand Down Expand Up @@ -830,6 +828,15 @@ def initial_operations_before_filling_the_form(driver):
driver.execute_script("location.reload(true);")
wait_and_handle_popup(driver)
sleep(0.5)
# if args.no_css then remove css
if args.no_css:
# Execute JavaScript to remove CSS
driver.execute_script("""
var styleElement = document.querySelector('style');
if (styleElement) {
styleElement.parentNode.removeChild(styleElement);
}
""")
# Clear previous requests
del driver.requests
# Go to the target website
Expand Down Expand Up @@ -1267,7 +1274,7 @@ def run_browser_instance(payloads, instance_number):
handle_unknown_exception(e)
# Initialize report file and processed payload file
this_threads_files = get_filename()
# If pause flag is set then go to target page and puase for one time
# If pause flag is set then go to target page and pause for one time
if args.pause:
driver.get(args.target)
pause_event.set()
Expand Down Expand Up @@ -1746,7 +1753,7 @@ def attempt_clusterbomb_fuzz(payloads_combinations, driver,this_threads_files, i
print(f"{BLUE}[+] Elements:Payloads: {RESET}{element}:{payload_file_path}")
print(f"{BLUE}[+] Button : {RESET}{args.button}")
print(f"{YELLOW}[+]--------------------------------------------------------------------------------------------------------------------------[+]")
print(f"\n\n{YELLOW}[+]--------------------------------------------------------------------------------------------------------------------------[+]\nINFO:{RESET} Press ENTER to puase the attack.\n{YELLOW}[+]--------------------------------------------------------------------------------------------------------------------------[+]\n{RESET}")
print(f"\n\n{YELLOW}[+]--------------------------------------------------------------------------------------------------------------------------[+]\nINFO:{RESET} Press ENTER to pause the attack.\n{YELLOW}[+]--------------------------------------------------------------------------------------------------------------------------[+]\n{RESET}")
# Create and start the threads
threads = []
start = 0
Expand All @@ -1771,7 +1778,7 @@ def attempt_clusterbomb_fuzz(payloads_combinations, driver,this_threads_files, i
thread_payloads = payloads[start:end]
# Create a thread with the target function and arguments
thread = threading.Thread(target=run_browser_instance, args=(thread_payloads,i)) #elements, i))
# Sleep while puase
# Sleep while pause
sleep_while_pause()
# Start the thread
thread.start()
Expand Down Expand Up @@ -1852,3 +1859,4 @@ def attempt_clusterbomb_fuzz(payloads_combinations, driver,this_threads_files, i
print(f"\n\n{RED}[+]--------------------------------------------------------------------------------------------------------------------------[+]\nERROR: {RESET}Refer Above Stack Trace\n{RED}[+]--------------------------------------------------------------------------------------------------------------------------[+]{RESET}")

### MAIN EXECUTION BLOCK ENDS ###

Loading

0 comments on commit 20c81c4

Please sign in to comment.