diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..031cf0da --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Folders we don't want to track +logs/ +__pycache__/ +venv/ + +# Files that BlackWidow creates +command.txt +queue.txt +run.flag +attack_lookup_table.txt +form_xss.txt +graph_mathematica.txt +successful_xss.txt +form_files/dynamic/ +successful_injections*.txt diff --git a/Classes.py b/Classes.py index 0db0c8cf..521f88f2 100644 --- a/Classes.py +++ b/Classes.py @@ -9,6 +9,7 @@ WebDriverException, InvalidElementStateException ) +from selenium.webdriver.common.by import By from urllib.parse import urlparse, urljoin import json @@ -481,7 +482,11 @@ def __init__(self, driver, url): logging.info("Init crawl on " + url) - def start(self, debug_mode=False): + def start(self, debug_mode=False, crawler_mode=False): + if(crawler_mode == False): + print("run both crawler module and attack module") + else: + print("only run the crawler module") self.root_req = Request("ROOTREQ", "get") req = Request(self.url, "get") self.graph.add(self.root_req) @@ -567,8 +572,10 @@ def start(self, debug_mode=False): #print(self.graph.toMathematica()) break - print("Done crawling, ready to attack!") - self.attack() + print("Done crawling") + if(crawler_mode == False): + print("Start Attacking") + self.attack() def extract_vectors(self): print("Extracting urls") @@ -657,18 +664,18 @@ def attack_event(self, driver, vector_edge): try: if event.event == "oninput" or event.event == "input": - el = driver.find_element_by_xpath(event.addr) + el = driver.find_element(By.XPATH, event.addr) el.clear() el.send_keys(payload) el.send_keys(Keys.RETURN) - logging.info("oninput %s" % driver.find_element_by_xpath(event.addr) ) + logging.info("oninput %s" % driver.find_element(By.XPATH, event.addr) ) if event.event == "oncompositionstart" or event.event == "compositionstart": - el = driver.find_element_by_xpath(event.addr) + el = driver.find_element(By.XPATH, event.addr) el.click() el.clear() el.send_keys(payload) el.send_keys(Keys.RETURN) - logging.info("oncompositionstart %s" % driver.find_element_by_xpath(event.addr) ) + logging.info("oncompositionstart %s" % driver.find_element(By.XPATH, event.addr) ) else: logging.error("Could not attack event.event %s" % event.event) @@ -828,7 +835,7 @@ def inspect_attack(self, vector_edge): successful_xss = set() # attribute injections - attribute_injects = self.driver.find_elements_by_xpath("//*[@jaekpot-attribute]") + attribute_injects = self.driver.find_elements(By.XPATH, "//*[@jaekpot-attribute]") for attribute in attribute_injects: lookup_id = attribute.get_attribute("jaekpot-attribute") successful_xss.add(lookup_id) @@ -942,7 +949,7 @@ def use_tracker(self, tracker, vector_with_payload): def inspect_tracker(self, vector_edge): try: - body_text = self.driver.find_element_by_tag_name("body").text + body_text = self.driver.find_element(By.TAG_NAME, "body").text for tracker in self.io_graph: if tracker in body_text: @@ -1377,7 +1384,7 @@ def rec_crawl(self): time.sleep(1) except UnexpectedAlertPresentException: logging.warning("Alert detected") - alert = driver.switch_to_alert() + alert = driver.switch_to.alert alert.dismiss() # Check if double check is needed... @@ -1431,7 +1438,7 @@ def rec_crawl(self): wait_json = driver.execute_script("return JSON.stringify(need_to_wait)") except UnexpectedAlertPresentException: logging.warning("Alert detected") - alert = driver.switch_to_alert() + alert = driver.switch_to.alert alert.dismiss() wait_json = driver.execute_script("return JSON.stringify(need_to_wait)") wait = json.loads(wait_json) @@ -1501,7 +1508,7 @@ def rec_crawl(self): # Try to clean up alerts try: - alert = driver.switch_to_alert() + alert = driver.switch_to.alert alert.dismiss() except NoAlertPresentException: pass diff --git a/Functions.py b/Functions.py index 192a4778..131daa4a 100644 --- a/Functions.py +++ b/Functions.py @@ -7,6 +7,7 @@ from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys from selenium.common.exceptions import StaleElementReferenceException, TimeoutException, UnexpectedAlertPresentException, NoSuchFrameException, NoAlertPresentException, ElementNotVisibleException, InvalidElementStateException +from selenium.webdriver.common.by import By from urllib.parse import urlparse, urljoin import json import pprint @@ -59,7 +60,7 @@ def xpath_row_to_cell(addr): def remove_alerts(driver): # Try to clean up alerts try: - alert = driver.switch_to_alert() + alert = driver.switch_to.alert alert.dismiss() except NoAlertPresentException: pass @@ -320,7 +321,7 @@ def execute_event(driver, do): try: if do.event == "onclick" or do.event == "click": - web_element = driver.find_element_by_xpath(do.addr) + web_element = driver.find_element(By.XPATH, do.addr) logging.info("Click on %s" % web_element ) if web_element.is_displayed(): @@ -329,60 +330,60 @@ def execute_event(driver, do): logging.warning("Trying to click on invisible element. Use JavaScript") driver.execute_script("arguments[0].click()", web_element) elif do.event == "ondblclick" or do.event == "dblclick": - web_element = driver.find_element_by_xpath(do.addr) + web_element = driver.find_element(By.XPATH, do.addr) logging.info("Double click on %s" % web_element ) ActionChains(driver).double_click(web_element).perform() elif do.event == "onmouseout": - logging.info("Mouseout on %s" % driver.find_element_by_xpath(do.addr) ) - driver.find_element_by_xpath(do.addr).click() - el = driver.find_element_by_xpath(do.addr) + logging.info("Mouseout on %s" % driver.find_element(By.XPATH, do.addr) ) + driver.find_element(By.XPATH, do.addr).click() + el = driver.find_element(By.XPATH, do.addr) # TODO find first element in body - body = driver.find_element_by_xpath("/html/body") + body = driver.find_element(By.XPATH, "/html/body") ActionChains(driver).move_to_element(el).move_to_element(body).perform() elif do.event == "onmouseover": - logging.info("Mouseover on %s" % driver.find_element_by_xpath(do.addr) ) - el = driver.find_element_by_xpath(do.addr) + logging.info("Mouseover on %s" % driver.find_element(By.XPATH, do.addr) ) + el = driver.find_element(By.XPATH, do.addr) ActionChains(driver).move_to_element(el).perform() elif do.event == "onmousedown": - logging.info("Click (mousedown) on %s" % driver.find_element_by_xpath(do.addr) ) - driver.find_element_by_xpath(do.addr).click() + logging.info("Click (mousedown) on %s" % driver.find_element(By.XPATH, do.addr) ) + driver.find_element(By.XPATH, do.addr).click() elif do.event == "onmouseup": - logging.info("Mouseup on %s" % driver.find_element_by_xpath(do.addr) ) - el = driver.find_element_by_xpath(do.addr) + logging.info("Mouseup on %s" % driver.find_element(By.XPATH, do.addr) ) + el = driver.find_element(By.XPATH, do.addr) ActionChains(driver).move_to_element(el).release().perform() elif do.event == "change" or do.event == "onchange": - el = driver.find_element_by_xpath(do.addr) - logging.info("Change %s" % driver.find_element_by_xpath(do.addr) ) + el = driver.find_element(By.XPATH, do.addr) + logging.info("Change %s" % driver.find_element(By.XPATH, do.addr) ) if el.tag_name == "select": # If need to change a select we try the different # options - opts = el.find_elements_by_tag_name("option") + opts = el.find_elements(By.TAG_NAME, "option") for opt in opts: try: opt.click() except UnexpectedAlertPresentException: print("Alert detected") - alert = driver.switch_to_alert() + alert = driver.switch_to.alert alert.dismiss() else: # If ot a - selects = el.find_elements_by_tag_name("select") + selects = el.find_elements(By.TAG_NAME, "select") for select in selects: form_select = Classes.Form.SelectElement( "select", select.get_attribute("name") ) if form_select in target_form.inputs: @@ -603,7 +604,7 @@ def form_fill(driver, target_form): #